在Django模型中使用request

2 投票
3 回答
4093 浏览
提问于 2025-04-18 06:02

我有两个模型

class Post(models.Model):
    user = models.ForeignKey(User, verbose_name='User')
    content = models.TextField(verbose_name='Text', max_length=4000)
    date = models.DateTimeField(verbose_name='Date', default=now())

class Vote(models.Model):
    vote = models.IntegerField(choices=VOTE, verbose_name='Vote')
    post = models.ForeignKey(Post, verbose_name='Post')
    user = models.ForeignKey(User, verbose_name='User')

还有一个视图,用来加载最近的15条帖子:

posts = Post.objects.all().order_by('-date')[:15]

现在我想知道在我所有查询结果中的活跃用户投票的信息

我考虑在帖子模型里加一个自定义的方法,这个方法会检查当前登录的用户,并获取投票对象:

def user_vote(self):
    try:
        data = Vote.objects.filter(post=self, user=request.user)
        return data.vote
    except ObjectDoesNotExist:
        #not voted

但是看起来Django不允许在模型中使用请求。还有其他的想法吗?

3 个回答

1

这不是django的问题,而是因为你的代码中没有找到request这个东西。如果你把request传给模型的方法,它就能正常工作。比如这样:

def user_vote(self, request):
        try:
            data = Vote.objects.get(post=self, user=request.user)
            return data.vote
        except Vote.DoesNotExist:
            #not voted

然后用你的Post实例这样调用它:

# Note the request being passed as a parameter
vote = post.user_vote(request)

更新:

如果你想获取某个用户的所有投票,可以这样做:

votes = Vote.objects.filter(post=self, user=request.user)
return reduce(lambda x, y: x.vote + y.vote, votes, 0) 

我们在最后加了个0,这样如果这个用户没有投票,就会返回0。这个方法会把所有的投票加起来并返回结果。

如果你不想把这些投票加起来,可以把这一行改成:

return reduce(lambda x, y: x.vote + y.vote, votes, 0) 

改成:

return map(lambda x, y: x.vote + y.vote, votes) 

这样就能得到一个包含request.user用户所有投票的列表。

1

我觉得你在找这个包:

https://pypi.python.org/pypi/django-crequest/1.0

描述:

crequest 可以让你在代码的任何地方获取到你 Django 应用程序当前的请求对象。

它的用法如下:

from crequest.middleware import CrequestMiddleware
current_request = CrequestMiddleware.get_request()
4

你可以像这样把用户当作参数传给方法:

def user_vote(self, user):

另外,我想你需要获取一个投票实例,而不是查询集,所以你应该使用 .get 方法,而不是 .filter

def user_vote(self, user):
    try:
        data = Vote.objects.get(post=self, user=user)
        return data.vote
    except ObjectDoesNotExist:
        #not voted

然后你可以用帖子实例来调用这个方法:

post.user_vote(request.user)

更新

Django 不允许在模板中使用带参数的方法。所以在你的情况下,最好把这个方法改成模板标签:

def get_user_vote(post, user):
    try:
        data = Vote.objects.get(post=post, user=user)
        return data.vote
    except ObjectDoesNotExist:
        #not voted

你可以在这里找到手册 https://stackoverflow.com/a/6493001/3291969

别忘了注册它哦 :)

撰写回答