Реляционный набор запросов не отображается должным образом в шаблоне
Я думаю, что это довольно простая проблема, но я пытаюсь отобразить в шаблоне все заголовки для определенной страницы, а внутри этого заголовка соответствующий текст. С этими моделями:
class Page(models.Model):
page_title = models.CharField(_("title of the page"), max_length=50)
category = models.ForeignKey('Category', on_delete=models.CASCADE)
def __str__(self):
return self.page_title
class Category(models.Model):
category_name = models.CharField(_("name of the category"), max_length=50)
def __str__(self):
return self.category_name
class Title(models.Model):
title = models.CharField(_("titulo"), max_length=50)
page = models.ForeignKey(Page, on_delete=models.CASCADE)
def __str__(self):
return self.title
class Text(models.Model):
title = models.ForeignKey(Title, verbose_name=_("titulo de la pagina a la que pertenece"), on_delete=models.CASCADE, default='')
content = models.TextField()
def __str__(self):
return f"{self.title}"
Я использую это представление для визуализации логики:
def index(request):
pages = Page.objects.all()
titles = Title.objects.filter(page__id=2)
for title in titles:
title_id = title.id
texts = Text.objects.filter(title__id=title_id)
context = {
'pages' : pages,
'titles' : titles,
'texts' : texts,
}
return render(request, 'index.html', context)
Но при таком подходе texts
дает мне только текст последнего заголовка, когда отображается таким образом в шаблоне:
{% for page in pages %}
<h1>{{page}}</h1>
{% for title in titles %}
<h3>{{title}}</h3>
{% for text in texts %}
<p>{{text}}</p>
{% endfor %}
{% endfor %}
{% endfor %}
Желаемый рендеринг будет выглядеть так:
все заголовки и тексты будут отображаться следующим образомTitle 1
Text of title 1
Title 2
Text of title 2
Title 3
Text of title 3
Для такого количества названий и текстов, которое имеется в базе данных. Каков был бы подход к этому?
Edit: текущий вывод показывает заголовки правильно, но текст всегда последний (в данном случае текст 3)
Проблема заключается в логике представления:
попробуйте это:
def index(request):
pages = Page.objects.all()
titles = Title.objects.filter(page__id=2)
title_id = []
for title in titles:
title_id.append(title.id)
texts = Text.objects.filter(title__id__in=title_id)
context = {
'pages' : pages,
'texts' : texts,
}
return render(request, 'index.html', context)
Также в models.py
измените class Text
как:
class Text(models.Model):
title = models.ForeignKey(Title, verbose_name="titulo de la pagina a la que pertenece", on_delete=models.CASCADE, default='')
content = models.TextField()
def __str__(self):
return self.content #here
Затем в шаблоне сделайте следующее:
{% for page in pages %}
<h1>{{page}}</h1>
{{texts}}
{% for text in texts %}
<h3>{{text.title}}</h3>
<p>{{text}}</p>
{% endfor %}
{% endfor %}
Надеюсь, это сработает!
Ответ был прост, поскольку я неправильно выполнял итерацию в шаблоне. Мне пришлось использовать _set.all
, чтобы получить правильные дочерние элементы.
{% for page in pages %}
<h1>{{page}}</h1>
{% for title in titles %}
<h3>{{title}}</h3>
{% for text in title.text_set.all %} # This
<p>{{text.content}}</p>
{% endfor %}
{% endfor %}
{% endfor %}