【问题标题】:Django Dynamic Object Filtering issue in Template模板中的 Django 动态对象过滤问题
【发布时间】:2020-08-10 05:00:37
【问题描述】:

我有一个页面,其中列出了帖子以及与每个帖子相关的照片。但是,我在从照片列表 QuerySet 过滤和发送照片时遇到问题,因为它在帖子列表查询集的循环下。知道如何运行过滤器以仅将照片作为模板中的相关帖子获取吗?

<h2> Posts: </h2>
{% for post in post_list %}

     {% include 'posts/list-inline.html' with post_whole=post  post_photos=photo_list %}

{% endfor %}

这里需要从 photo_list 中过滤掉与单个帖子有外键关系的多个对象。 QuerySet 过滤器在模板中不起作用。

更新:缩小模型供参考:

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    post_text = models.CharField(max_length=5000, null=True, blank=True)
    selection = models.ForeignKey(Selection, null=True, blank=False, on_delete=models.SET_NULL)
    timestamp = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

class PostPhoto(models.Model):
    # to apply multiple photos to same post id
    post_id = models.ForeignKey(Post, null=True, blank=True, on_delete=models.CASCADE)
    photo = models.ImageField(upload_to='img/', blank=True, null=True)
    thumbnail = models.ImageField(upload_to='tmb/', null=True, blank=True, editable=False)

【问题讨论】:

  • 请分享相关模型。
  • @WillemVanOnsem 我已经编辑并添加了相关模型。

标签: django django-views django-templates django-queryset


【解决方案1】:

您可以通过以下方式获取相关 PostPhoto 对象的列表:

mypost<b>.postphoto_set.all()</b>

所以在你的模板中,你可以使用:

<h2> Posts: </h2>
{% for post in post_list %}
     {% include 'posts/list-inline.html' with post_whole=post  post_photos=post.postphoto_set.all %}
{% endfor %}

(不带括号,因为模板会自动调用可调用对象)。

为避免 N+1 问题,在视图中,您最好使用.prefetch_related(..) clause [Django-doc] 检索Posts:

posts = Post.objects<b>.prefetch_related('postphoto_set')</b>

【讨论】:

  • 问题是 post_list 包含多个帖子......在这些多个帖子中,每个帖子都有多张照片......所以在这个模板中,我从视图中得到的只是一个 QuerySet post_list 下的多个帖子对象和 photo_list 下多个 PostPhoto 对象的相关 QuerySet。
  • @Jayesh:在list-inline.html 中,您需要对post_photos 进行迭代,然后逐个渲染这些内容。
  • 哦,我错过了点之前的帖子......它有效......谢谢......虽然我完全不明白你所说的N+1问题......
  • @Jayesh:如果你渲染 n 个帖子,它会导致 n+1 个查询:一个是获取帖子,一个是 n 获取Post 对象的PostPhotos。通过使用.prefetch_related。 Django 将使用一个额外的查询来获取 all 内存中相关的PhotoPosts,然后在 Django/Python 级别进行连接。因此,您执行两个查询,而不是 n+1 个查询。
  • 从性能的角度来看,这声音非常棒。我现在就试试……
猜你喜欢
  • 1970-01-01
  • 2015-11-23
  • 2021-11-17
  • 2018-04-12
  • 2011-06-18
  • 2017-04-19
  • 2020-07-02
  • 2012-10-16
  • 1970-01-01
相关资源
最近更新 更多