shellfly / django-vote

Simple vote for django
http://django-vote.readthedocs.io
Apache License 2.0
158 stars 49 forks source link

Difference between downvote and delete #50

Closed mihovilm closed 7 years ago

mihovilm commented 7 years ago

Hi!

Whats the diff. between upvoting and then downvoting,

and just upvoting and deleting the vote?

Makes no sense to me to have a downvoting feature when it's the same as delete (doesn't go into negative)

shellfly commented 7 years ago

https://github.com/shanbay/django-vote/blob/master/vote/models.py#L70

vote score can be negative.

mihovilm commented 7 years ago

Hmm, not working for me. When count is 0 (untouched object/instance), votes.down returns false for any of my users. capture

shellfly commented 7 years ago

a.vote_score

mihovilm commented 7 years ago

capture

mihovilm commented 7 years ago

Maybe reinstall thru pip?

shellfly commented 7 years ago

The latest version is 2.1.4 and also check if you have define a custom save method on your a model.

mihovilm commented 7 years ago

I have 2.1.4, and nope, I only have 'save' overriding on my views/forms (CreateView etc.)

a is not a model, just an instance of my Question model.

mihovilm commented 7 years ago

vote_score doesn't work for me at all, check attachment.

I'll try this out on a new model. capture

shellfly commented 7 years ago

Can you paste the Question model here?

mihovilm commented 7 years ago

Sure capture

I believe the relationship between num_vote_up and num_vote_down is messed up.

or something else changed my vote_score variable, and it became a constant.

mihovilm commented 7 years ago

a is now Newmodel.objects.get(id=1) capture

num_vote_down doesn't register votes.down at all

mihovilm commented 7 years ago

Okay I see what the problem is.

The vote_score that shows up in shell and is a model attribute, is different from the one that shows up in the admin panel (the right one)

I don't know why is this happening. Here's my admin panel listing for the same 'a' object as above. capture

flyudvik commented 7 years ago

+1 Have the same problem.

shellfly commented 7 years ago

@mihovilm @amywoodehy In voting actions we generate a new instance by select_for_update. So the change does't reflect to the original instance, you have to fetch the instance again to see the change.

https://github.com/shanbay/django-vote/blob/master/vote/managers.py#L58

flyudvik commented 7 years ago

ok, I see change in vote_score, but count still returns the same result as before down vote.

Model.objects.first().votes.down(1)  # True
obj = Model.objects.first()
obj.votes.count()  # 0  -- this still bothers me
obj.vote_score  # -1
obj.num_vote_down  # 1

And Model.objects.first().votes.user_ids() returns empty queryset.

flyudvik commented 7 years ago

Oh, I understand now. But why was it necessary to make votes.count(action) return number of votes by action? I expected it to return all votes. Same for user_ids(action)

shellfly commented 7 years ago

If you just want a score you can use vote_score field, the count and user_ids have to distinguish by action because of we support down vote now.

Claytone commented 5 years ago

Can any of you give an explanation on how to get negative scores working? Here's what I have:

patch = Patch.objects.filter(id=post_id)[0]
patch.vote_score      #0 

if patch.votes.exists(id):
    patch.votes.delete(id)

patch.votes.down(id)
patch.vote_score      #0

patch.save()
new_patch = Patch.objects.filter(id=post_id)[0]
new_patch.vote_score     #0

I know this is an old thread, but I feel like I've looked everywhere for an answer and haven't found one.

shellfly commented 5 years ago

@Claytone which version are you using? do you have a custom save method on your Patch model?

Cdingram commented 5 years ago

I ran into the same (similar) issue, I'm using version 2.1.7 and I have no custom save method on my model. I've realized that it's due to that fact that you cannot save the object for whatever reason until you fetch the new instance:

obj.votes.up(1)
obj.votes.up(2)
obj.votes.down(3)

obj = Model.objects.first()
obj.save()

obj.vote_score #1
obj.votes.count() #2
obj.votes.count(1) #1

but if you flip the save and the fetch

obj.votes.up(1)
obj.votes.up(2)
obj.votes.down(3)

obj.save()
obj = Model.objects.first()

obj.vote_score #0
obj.votes.count() #2
obj.votes.count(1) #1

so although the changes don't reflect in the current instance as you mentioned, this means that you cannot save the instance at any point unless you fetch it again first. I'm not sure this is intentional design because if you're updating several fields along with a vote on a model you have to query for the model again before you save it, however if you follow the rule always fetch first if you have to save it should work as intended. Hope this helps

Claytone commented 5 years ago

@shellfly Hey, sorry for the late reply, but I've tried @Cdingram 's solution and still couldn't get it to work. Maybe you can shed some light on this?


    patch = Patch.objects.filter(id=post_id)[0]
    id = request.user.id
    print(patch.vote_score) # 0
    patch.votes.up(id)
    #tried with and without this line
    patch = Patch.objects.filter(id=post_id)[0] 
    patch.save()
    print(patch.vote_score) # 0
    print(patch.votes.count(id)) # 0
Claytone commented 5 years ago

Resolved the issue, but I'm not sure what's different. Here's the final block of code, which behaves as expected:


patch = Patch.objects.filter(id=post_id)[0]
    id = request.user.id

    if direction=="up":
        patch.votes.up(id)
    elif direction=="down":
        patch.votes.down(id)
    elif direction == "clear":
        patch.votes.delete(id)
    else:
        print("ERR")

    patch = Patch.objects.filter(id=post_id)[0]
    patch.save()
    print(patch.vote_score)