【问题标题】:Django order_by ForeignKey set modelsDjango order_by ForeignKey 设置模型
【发布时间】:2012-03-01 07:29:10
【问题描述】:

我有以下 django 模型

class Post(models.Model):
    title = models.CharField(max_length=240)

class Comment(models.Model):
    post = models.ForeignKey(Post)
    date = models.DateTimeField(auto_now_add=True)

我需要一个 QuerySet 的 cmets,首先按邮寄顺序排序,然后按日期排序。 但帖子必须按其最新评论排序。

如果我可以在 QuerySet order_by 中使用模型方法,它会是这样的:

class Post(models.Model):
    title = models.CharField(max_length=240)

    def get_last_comment_date(self):
        return self.comment_set.order_by('-date')[0].date

我需要的顺序可能是:

Comment.objects.all().order_by('post__get_last_comment_date', '-date')

但不幸的是,order_by 中的方法是不允许的。

请帮忙。我可以这样订购吗?

【问题讨论】:

    标签: python django


    【解决方案1】:

    您不能使用 order_by lookups 中的方法,因为它们已转换为 SQL

    那么,为什么不将 get_last_comment_date 转换为字段?例如使用signal receiver:

    from django.db.models import signals
    
    class Post(models.Model):
        title = models.CharField(max_length=240)
        last_comment_date = models.DateField(null=True, blank=True)
    
    def post_last_comment_date(sender, instance=None, **kwargs):
        try:
            last_comment_date = self.comment_set.order_by('-date')[0].date
        except Comment.DoesNotExist:
            return
    
        if last_comment_date != comment.post.last_comment_date:
            comment.post.last_comment_date = last_comment_date
            comment.post.save()
    
    signals.post_save.connect(post_last_comment_date, sender=Comment)
    

    现在,您可以:Comment.objects.order_by('post__last_comment_date', '-date')

    【讨论】:

    • 谢谢!我担心,当特定帖子的新评论出现时,我将不得不将“last_comment_date”字段添加到 Post 模型并每次更新它。但是您的解决方案要好得多!
    • 糟糕,我之前的评论似乎太快了。此解决方案将更新每个新评论的字段。它可以工作(对代码进行一些更正,即将“self”重命名为“instance”),但它会在每条新评论上增加数据库的额外负载吗?
    • 是的,我们正在交易发表评论时发生的 2 个(极端情况下为 3 个)查询,而不是显示时的许多查询。对我来说听起来很公平。
    猜你喜欢
    • 2016-04-29
    • 1970-01-01
    • 2013-02-19
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多