问题
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