[英]How to write select query in django in chain of one-to-many relationship?
[英]Django: How to Join One-to-many relationship? / Show joined query in template
我是 Django 的新人。我正在嘗試制作 craiglist 的克隆。 目前我有模型:帖子和媒體(圖像)。 一篇文章可以有很多媒體。 我想顯示用戶在創建帖子時發布的第一張圖片以及有關索引頁面上帖子的信息。 不幸的是,當我引用帖子時我無法正確加入媒體,反之亦然。 如何在索引模板中正確顯示帖子和媒體實例?
楷模:
class Post(models.Model):
title = models.CharField(max_length=50)
description = models.CharField(max_length=1500)
user = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
subcategory = models.ForeignKey(Subcategory, on_delete=models.SET_NULL, null=True)
price = models.DecimalField(max_digits=12, decimal_places=2)
city = models.CharField(max_length=200)
class Media(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
name = models.CharField(max_length=500, null=True, blank=True)
photo = models.ImageField(upload_to='photo/%Y/%m/%d/', null=True, blank=True)
意見:
def index(request):
posts = models.Media.objects.all()
paginator = Paginator(posts, 2)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, 'aggregator/index.html', {'page': page_obj})
index.html 模板:
{% for media in page %}
<div class="col">
<div>
<p>Picture</p>
</div>
<div>
<h4><a href="{% url 'show_post' post_id=media.post.id %}">{{ media.post.title|upper }}</a></h4>
</div>
<div>
<h5>{{media.post.price}}$</h5>
</div>
<div>
<h6>{{media.post.city}}</h6>
</div>
</div>
{% endfor %}
又是這樣。 如何正常加入與帖子相關的第一媒體? 就像所附的屏幕截圖一樣。
我找到了從媒體獲取帖子的解決方案:
posts = models.Media.objects.all()
而不是自己獲取帖子(我知道這是非常錯誤的)因為我不明白如何加入媒體: select_related和prefetch_related不起作用 - 有這樣的錯誤:
posts = models.Post.objects.select_related('Media').all()
Invalid field name(s) given in select_related: 'Media'. Choices are: user, category, subcategory
要在 Django 模板中顯示連接查詢的結果,您需要將查詢集傳遞給模板上下文,然后使用 for 循環遍歷查詢集中的對象。
以下是如何在視圖 function 中執行此操作的示例:
from django.shortcuts import render from.models import Model1, Model2 def view_function(request): queryset = Model1.objects.select_related('model2').all() return render(request, 'template.html', {'objects': queryset})
然后,在您的模板中,您可以使用 for 循環遍歷查詢集中的對象,並使用點表示法訪問每個 object 的字段。
例如:
{% for obj in objects %} {{ obj.field1 }} - {{ obj.model2.field2 }} {% endfor %}
您可以預取:
def index(request):
posts = models.Post.objects.prefetch_related('media_set')
paginator = Paginator(posts, 2)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, 'aggregator/index.html', {'page': page_obj})
然后在模板中渲染:
{% for post in page %} <div class="col"> <div> {% if post.media_set.all.0.photo %} <img src="{{ post.media_set.all.0.photo.url }}"> {% endif %} </div> <div> <h4><a href="{% url 'show_post' post_id=post.pk %}">{{ post.title|upper }}</a></h4> </div> <div> <h5>{{ post.price }}$</h5> </div> <div> <h6>{{ post.city }}</h6> </div> </div> {% endfor %}
.prefetch_related
甚至不是必需的,但它會減慢視圖速度,因為那樣它會對每個Post
進行查詢,而不是一個額外的查詢來獲取所有Media
對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.