【问题标题】:How to annotate a related object to queryset, in cases it exists, and None otherwise? (Django)如何将相关对象注释到查询集,如果它存在,否则没有? (姜戈)
【发布时间】:2015-11-14 17:27:28
【问题描述】:

伙计们,我有一个 Django 聊天应用程序,人们可以在其中组成群组并在其下发布回复。每当用户查看组中的回复时,都会为所述回复和所述用户创建(并存储)“看到的对象”。

这样,我可以在每个组中每个用户的所有看不见的回复前显示一个新标签

我的问题是:对于回复查询集中的每个对象,我如何才能为特定用户附加与每个回复对应的可见对象?如果不存在这样的对象,我认为它将保持无。

相关型号有:

class Reply(models.Model):
    text = models.TextField(validators=[MaxLengthValidator(500)])
    writer = models.ForeignKey(User)
    submitted_on = models.DateTimeField(db_index=True, auto_now_add=True)

class Seen(models.Model):
    seen_user = models.ForeignKey(User)
    seen_at = models.DateTimeField(auto_now_add=True)
    which_reply = models.ForeignKey(Reply)

为用户看到的回复创建看到的对象;它们不是以其他方式创建的。

【问题讨论】:

    标签: python django django-queryset


    【解决方案1】:

    您可以使用Prefetch 对象执行此操作:
    https://docs.djangoproject.com/en/1.7/ref/models/querysets/#prefetch-related

    例如

    seen_qs = Seen.objects.filter(user=request.user)
    replies_qs = Reply.objects.prefetch_related(
        Prefetch('seen_set', queryset=seen_qs)
    )
    

    在 Django

    seen_for = {
        seen.which_reply_id: seen
        for seen in Seen.objects.filter(user=request.user)
    }
    replies_qs = Reply.objects.filter(whatever)
    
    # you could attach the Seen instance to each Reply
    # or just make a paired list e.g.
    replies = [
        (reply, seen_for.get(reply.pk))  # None if not found
        for reply in replies_qs
    ]
    

    【讨论】:

    • 如果相关对象有唯一的存在,我也可以使用select_related吗?
    • 是的,select_related 适用于 ForeignKey 和 OneToOne...这里有一个反向外键,因此您需要使用查询集进行预取(ManyToMany 相同)
    • 一个问题:我使用的是 Django 1.5,这意味着我不能使用 queryset=seen_qs
    • 嗯,当我测试它时,似乎 object.0object.1 是模板的方式。
    • 或者使用“解构赋值”(元组解包),例如{% for reply, seen in replies %}
    猜你喜欢
    • 2021-09-27
    • 1970-01-01
    • 2023-03-19
    • 2018-03-02
    • 2017-03-28
    • 2021-06-03
    • 2021-10-12
    • 2021-09-13
    • 2021-03-14
    相关资源
    最近更新 更多