【问题标题】:Django. Restrict each user to only vote once姜戈。限制每个用户只能投票一次
【发布时间】:2013-07-25 17:26:52
【问题描述】:

我有一种情况,我对两种解决方案中的任何一种都感到满意,这取决于哪个更可行/可能。我有一个显示事件的页面。该事件的名称可能不一定正确,因此用户可以选择建议更正。这些更正存储在它们自己的表中,并与事件有外键关系。提出建议后,用户可以对该建议投赞成票或反对票。我需要将每个登录用户的最大投票数限制为 1。我完全不知道该怎么做。

我的理想解决方案:显示多达五个建议。每个登录用户都可以对这五个建议中的每一个进行投票。每次一次。

我不太理想但仍然可以接受的解决方案:显示的建议多达五个。登录用户只能对五项建议中的一项投票赞成或反对。

我不确定哪个更实用。我将为活动提供我的模型和建议的名称。如果您还需要查看其他内容,请告诉我。提前致谢!

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)

【问题讨论】:

  • 你没有跟踪user谁在任何地方投票。
  • 要限制投票数量,您需要一个包含用户详细信息的投票实体模型。

标签: django django-models


【解决方案1】:
class Vote(models.Model):

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

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

正如一些 cmets 建议的那样,您应该为您的 User 建立一个模型(在我的示例中,我只是假设您已经拥有)。

你可以用这个模型做什么?正是您需要做的!

假设您有一个允许用户投票的视图。你会想要覆盖它的post()(或is_valid(),这取决于)方法来检查用户是否可以投票:

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!')

此外,如果您只想允许每个用户投一票,请将您检索到的用户值传递给 get_or_created

希望这些指南对您有所帮助:)

【讨论】:

  • 是的,完美。很抱歉使用User,我意识到这可能会造成混淆。不要将我的代码视为“完美”,只需将其用作了解其工作原理的指南(a.k.a.:这一切都有意义吗?)
  • 您的 post() 方法是进入Vote 模型还是进入具有投票功能的视图?
  • 具有投票功能的视图,模型没有post 方法:)
  • 嘿,所以我一直在处理您的答案,这很棒。我可以说我已经接近了,但我在想,get_or_create 不会总是返回 true 吗?因为如果用户没有投票,它会创建它并且它会存在。如果用户有,它会“得到”它并且它仍然存在吗?我也不太清楚为什么你有vote, created 而不仅仅是created
  • 阅读文档 :) get_or_create 返回一个元组:对象和一个布尔值,如果它被创建则计算为 True,如果它已经存在则返回 False。这就是为什么你可以依靠它! docs.djangoproject.com/en/dev/ref/models/querysets/…
猜你喜欢
  • 1970-01-01
  • 2019-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 2010-10-06
  • 2011-03-26
  • 1970-01-01
相关资源
最近更新 更多