Django Search Query comparing votes and post age with Annotate

132 Views Asked by At

I trying to make a django query to get posts order by VOTES - POST AGE.

Example:

Normal Posts

1 - Hello World (10 votes) (Posted today)
2 - Stackoverflow ( 12 votes) (Posted 2 days ago)
3 - StackExchange ( 30 votes ) (Posted 19 days ago)

So when I filter query by annotate, I want this:

1 - StackExchange ( 30 votes - 19 days ago = 11 points)
2 - Hello World ( 10 votes - 0 days ago = 10 points)
3 - Stackoverflow ( 12 votes - 2 days ago = 10 points)

I try:

class DiffDays(Func):
    function = 'DATEDIFF'
    template = "%(function)s(%(expressions)s)"


class CastDate(Func):
    function = 'DATE_FORMAT'
    template = "%(function)s(%(expressions)s, '%%%%Y-%%%%m-%%%%d')"


list_posts = posts.extra(
    select={'pub_date': "DATE_FORMAT(pub_date,'%%%%Y-%%%%m-%%%%d')"}
).annotate(
    diff_days=DiffDays(
        CastDate(today), F('pub_date')), output_field = DecimalField()
).annotate(
    days_votes=ExpressionWrapper(
        F('n_votes') - F('diff_days'), output_field=IntegerField())
).order_by('days_votes')

but I'm getting: 'IntegerField' object has no attribute 'resolve_expression'

1

There are 1 best solutions below

7
On

now output_field in annotate for diff_days is an argument of the annotate, but it have to be an argument of DiffDays, so your need add brackets for put it inside func DiffDays

today = today.strftime('%Y-%m-%d')

annotate(
    diff_days=DiffDays(
        (today, F('pub_date')), output_field=DecimalField())
      #^^^                                                ^^^
)