如何在Django中创建投票模型?

时间:2016-01-17 11:55:39

标签: django django-models

我有一个名为帖子的模型,用户可以投票。如果用户已投票,则他/她只能在此之后将其投票。我该如何实现这个系统?

我目前的模型看起来像这样:

class Post(models.Model):
    title = models.CharField(max_length = 140)
    user = models.ForeignKey('Auth.user')
    votes = models.IntegerField(default = 0)

制作另一个名为Vote的模型并将其链接到Post更好吗?如果是这样,我该如何以可与大量用户进行扩展的方式进行操作?

2 个答案:

答案 0 :(得分:2)

您解释的情况说,post只能获得up票。

当你需要持有投票的人时,我们需要继续投票并且是用户

class Post(models.Model):
    title = models.CharField(max_length = 140)
    user = models.ForeignKey('Auth.user')

    def votes_count(self):
        return self.votes.all().count()

class Vote(models.Model):
    class Meta:
        unique_together = [('post', 'user')]

    post = models.ForeignKey(Post, related_name='votes')
    user = models.ForeignKey('auth.User')

答案 1 :(得分:1)

一种方法是使用unique_together创建新模型:

class Post(models.Model):
    title = models.CharField(max_length = 140)
    user = models.ForeignKey(User, related_name="user_posts")
    votes = models.IntegerField(default = 0)

    def upvote(self, user):
        try:
            self.post_votes.create(user=user, post=self, vote_type="up")
            self.votes += 1
            self.save()                
        except IntegrityError:
            return 'already_upvoted'
        return 'ok'


    def downvote(self, user):
        try:
            self.post_votes.create(user=user, post=self, vote_type="down")
            self.votes -= 1
            self.save()                
        except IntegrityError:
            return 'already_downvoted'
        return 'ok'

class UserVotes(models.Model):
    user = models.ForeignKey(User, related_name="user_votes")
    post = models.ForeignKey(Post, related_name="post_votes")
    vote_type = models.CharField()


    class Meta:
        unique_together = ('user', 'post', 'vote_type')

这样,您可以在数据库中创建索引,这样可以更快地在表中进行搜索,并确保没有重复数据进入数据库。

示例:

# say, user is logged in
post = Post(user=request.user, 'Awesome post')
post.save()

# another user
user = request.user
# he hits the upvote button, 'post' is Post object
res = post.upvote(user)
if 'ok' in res:
    return HttpResponse('OK')
return HttpResponse('ALREADY_UPVOTED')

我没有测试它顺便说一句。