【问题标题】:Using request in django model在 Django 模型中使用请求
【发布时间】:2014-06-27 15:28:08
【问题描述】:

我有 2 个模型

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 不允许在模型中使用请求。 还有其他想法吗?

【问题讨论】:

    标签: python django django-models


    【解决方案1】:

    您可以像这样将用户作为参数传递给方法:

    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 不允许在模板中使用带参数的方法。因此,在您的情况下,最好将此方法重构为模板标签:

    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

    别忘了注册 :)

    【讨论】:

    • 经过长时间的思考,我决定使用@dimamobile 的建议来创建自定义模板标签。无论如何,谢谢大家的帮助。
    【解决方案2】:

    这不是 django 问题,这是因为 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 用户的所有投票的列表

    【讨论】:

    • @dimamobile 修复了它。
    • 感谢@PatrickBassut 和@dimamobile 提供这个有用的提示,但我需要为多个帖子调用我的user_vote 实例(例如最后15 个帖子)。我应该尝试调用 user_vote 并在模板中传递request 参数吗?
    【解决方案3】:

    我认为您正在寻找这个包裹: https://pypi.python.org/pypi/django-crequest/1.0

    说明:

    crequest 会从代码中的任何位置为您带来 django 应用程序的当前请求对象。

    它是这样使用的:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-15
      • 2020-02-11
      • 2017-10-02
      • 2019-07-27
      • 2017-07-13
      • 2020-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多