模板中的 Django 动态对象过滤问题
Posted
技术标签:
【中文标题】模板中的 Django 动态对象过滤问题【英文标题】:Django Dynamic Object Filtering issue in Template 【发布时间】: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 我已经编辑并添加了相关模型。 【参考方案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] 检索Post
s:
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
对象的PostPhoto
s。通过使用.prefetch_related
。 Django 将使用一个额外的查询来获取 all 内存中相关的PhotoPost
s,然后在 Django/Python 级别进行连接。因此,您执行两个查询,而不是 n+1 个查询。
从性能的角度来看,这声音非常棒。我现在就试试……以上是关于模板中的 Django 动态对象过滤问题的主要内容,如果未能解决你的问题,请参考以下文章