我有两个模特
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]
现在,我希望获得有关所有查询集对象中活动用户投票的信息
我想过Post模型中的自定义方法,它会检查登录的用户并获得投票对象:
def user_vote(self):
try:
data = Vote.objects.filter(post=self, user=request.user)
return data.vote
except ObjectDoesNotExist:
#not voted
但似乎django不允许在模型中使用请求。 还有其他想法吗?
答案 0 :(得分:2)
您可以将user作为参数传递给这样的方法:
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实例调用这个方法:
post.user_vote(request.user)
<强>更新强>
Django不允许在模板中使用带参数的方法。因此,在您的情况下,最好将此方法重构为templatetag:
def get_user_vote(post, user):
try:
data = Vote.objects.get(post=post, user=user)
return data.vote
except ObjectDoesNotExist:
#not voted
找到手册
不要忘记注册它:)
答案 1 :(得分:1)
这不是django问题,因为请求不在代码范围内的任何地方。如果您将请求传递给模型的方法,它将起作用。类似的东西:
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
用户
答案 2 :(得分:1)
我认为你正在寻找这个包: https://pypi.python.org/pypi/django-crequest/1.0
说明
crequest将从您的代码中的任何位置为您带来django应用程序的当前请求对象。
它的用法如下:
from crequest.middleware import CrequestMiddleware
current_request = CrequestMiddleware.get_request()