django-vote
django-vote copied to clipboard
Object.votes.all(user_id) only returns a queryset of objects that I have Up voted
I have a user who has up-voted 4 items in total. When I then use object1.votes.down(user_id), it does decrement the vote as it should but then, If I make the query Objects.votes.all(user_id), that query only returns 3 items. I'm using the django shell and this is the exact code that I am executing.
>>> toppings = Toppings.votes.all(1)
>>> toppings
<QuerySet [<Toppings: sprinkles>, <Toppings: hot fudge>, <Toppings: whipped cream>, <Toppings: cherries>] >
>>> t1 = toppings[0]
>>> t1
<QuerySet [<Toppings: sprinkles>]>
>>> t1.votes.down(1)
True
>>> Toppings.votes.all(1)
<QuerySet [<Toppings: hot fudge>, <Toppings: whipped cream>, <Toppings: cherries>] >
Can someone let me know if I am using this incorrectly please?
After some experimenting with the api, it looks like both method all() and user_ids() have an 'action' option and instead of taking action=UP and action=DOWN as params, we have to pass 0 for 'UP' and 1 for 'DOWN' which isn't outlined in the docs. So when is use Object.votes.all(user_pk, action=1) I get the full query of 4 items. And then looping through them, I get what I am looking for.
>>> toppings = Toppings.votes.all(1, action=1)
>>> for t in toppings:
.... t.votes.user_ids().values()
<QuerySet [{'id': 14, 'user_id': 20, 'content_type_id': 8, 'object_id': 8, 'action': 0, 'create_at': datetime.datetime(2020, 10, 3, 21, 52, 50, 772113, tzinfo=<UTC>)}, {'id': 8, 'user_id': 1, 'content_type_id': 8, 'object_id': 8, 'action': 0, 'create_at': datetime.datetime(2020, 10, 3, 20, 45, 57, 572971, tzinfo=<UTC>)}]>
<QuerySet []>
<QuerySet []>
<QuerySet []>
or
>>> toppings = Toppings.votes.all(1, action=1)
>>> for t in toppings:
.... t.votes.user_ids(1).values()
<QuerySet []>
<QuerySet [{'id': 16, 'user_id': 20, 'content_type_id': 8, 'object_id': 9, 'action': 1, 'create_at': datetime.datetime(2020, 10, 3, 22, 20, 16, 62588, tzinfo=<UTC>)}, {'id': 9, 'user_id': 1, 'content_type_id': 8, 'object_id': 9, 'action': 1, 'create_at': datetime.datetime(2020, 10, 3, 20, 54, 42, 92675, tzinfo=<UTC>)}]>
<QuerySet [{'id': 17, 'user_id': 20, 'content_type_id': 8, 'object_id': 10, 'action': 1, 'create_at': datetime.datetime(2020, 10, 3, 22, 20, 27, 166642, tzinfo=<UTC>)}, {'id': 12, 'user_id': 1, 'content_type_id': 8, 'object_id': 10, 'action': 1, 'create_at': datetime.datetime(2020, 10, 3, 21, 9, 45, 38825, tzinfo=<UTC>)}]>
<QuerySet [{'id': 13, 'user_id': 20, 'content_type_id': 8, 'object_id': 11, 'action': 1, 'create_at': datetime.datetime(2020, 10, 3, 21, 40, 45, 147928, tzinfo=<UTC>)}, {'id': 10, 'user_id': 1, 'content_type_id': 8, 'object_id': 11, 'action': 1, 'create_at': datetime.datetime(2020, 10, 3, 21, 4, 50, 321174, tzinfo=<UTC>)}]>
Is there a way to just query all of the voted objects for a user and then ill just sort on the actions field when the information is returned with the values() method?
There is a UP and DOWN constant in vote.models that you can import and use instead of using the number 0 or 1 directly.
the down action was supported after so the the all and user_ids are using UP as the default action to make it back compatible.
I'm not sure what's the exact use case for you. I use the below pattern a lot, let me know if it helps. Basically there is a annotate method, you can use it on a QuerySet , it will add is_vote_up and is_vote_down property for every object based on the passed user.
queryset = Toppings.objects.filter({some query}).order_by('-num_vote_up')
queryset = Toppings.votes.annotate(queryset, request.user.pk)