Django. Restrict each user to only vote once

佐手、 提交于 2020-01-03 05:44:09

问题


I have a situation and am happy with either one of two solutions, depending on which is more feasible/possible. I have a page that displays an event. That event's name may not necessarily be correct, and so users have the option to suggest corrections. Those corrections are stored in their own table with an Foreign Key relationship to the event. Once a suggestion has been made, users can vote up or down on the suggestion. I need to restrict each logged in user's maximum vote to 1. I don't have the slightest idea how to do this.

My ideal solution: There are as many as five suggestions displayed. Each logged in user can vote on each of these five suggestions. Once on each.

My less ideal, but still acceptable solution: There are as many as five suggestions displayed. A logged in user is allowed to vote up or down on only one of the five suggestions.

I'm not sure which is more practical. I'll provide my models for the event and the suggested name. Please let me know if there's something else you need to see. Thanks in advance!

class Event(models.Model):
    def __unicode__(self):
        return unicode(self.id)
    id = models.BigIntegerField(blank = 'TRUE', primary_key='TRUE')
    version = models.IntegerField(default = 0)
    views = models.IntegerField(default = 0)
    created = models.DateTimeField(editable = False)
    modified = models.DateTimeField()
    trained = models.BooleanField(default = False)
    type = models.SmallIntegerField(default = 0)
    def save(self, *args, **kwargs):
        if not self.id:
            self.created = datetime.datetime.today()
        self.modified = datetime.datetime.today()
        super(Event, self).save(*args, **kwargs)


class suggestedName(models.Model):
    def __unicode__(self):
        return unicode(self.name)
    name = models.CharField(max_length=200, blank = 'TRUE', null = 'TRUE')
    votes = models.IntegerField(default = 0)
    event = models.ForeignKey(Event)

回答1:


class Vote(models.Model):

    class Meta:
        unique_together = (('userprofile','suggestedName'),)

    userprofile = models.ForeignKey(UserProfile)
    suggestedName = models.ForeignKey(suggestedName)
    event = models.ForeignKey(Event)

As some comments suggest, you should have a model for your User (which, in my example, I'm simply assuming you already have).

What can you do with this model? Exactly what you need to do!

Suppose you have a view that allows a user to vote. You'd want to override its post() (or is_valid(), it depends) method to check if the user can vote or not:

def post(self, request, *args, **kwargs):
    # - retrieve the user_profile
    # - retrieve the suggestedName he voted for
    # - query the votes to see if this combination of user_profile + suggestedName already exists

    vote, created = Vote.objects.get_or_create(
                        userprofile=userprofile, 
                        suggestedName=suggestedName, 
                        event=event
                    )

    # get_or_create will return a tuple
    # where created is True if the method created the Vote
    # False if there was a vote for this user and this name already
    # You now want to use the value from 'created' 
    # to decide wether the vote is valid or not

    if not created:
       return HttpResponse('You already voted for this, cheater')
    else:
       return HttpResponse('Awesome, thanks for voting!')

Furthermore, if you want to allow just 1 vote per user, pass to get_or_created just your retrieved user value.

Hope these guidelines help you out a bit :)



来源:https://stackoverflow.com/questions/17864783/django-restrict-each-user-to-only-vote-once

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!