Object_list 模板中的数据不正确
Object_list does not show correct data in template
我在 Django 模板中遇到了一个奇怪的问题。它是一个用于显示文章列表的模板,我会为他们中的每个人显示一个关键字列表,我称之为关键概念。
奇怪的是,显示的不是关键概念列表,而是使用该关键概念的文章列表。
在我的项目的E/R图表和模型及模板下方:
Models.py
class KeyConceptModel(models.Model):
concept_text = models.CharField(max_length=50)
def __str__(self):
return self.concept_text
def get_absolute_url(self):
return reverse("keyconceptManuscriptusView", kwargs={"pk": self.pk})
class Meta:
verbose_name = "Concetto chiave"
verbose_name_plural = "Concetti chiave"
class PostModel(models.Model):
post_title = models.CharField(max_length=70)
post_short_description = models.TextField(max_length=200)
post_contents = models.TextField()
post_publishing_date = models.DateTimeField(auto_now=False, auto_now_add=True)
post_author = models.ForeignKey(AuthorModel, on_delete=models.CASCADE)
post_keyconcept = models.ManyToManyField(KeyConceptModel)
slug = models.SlugField(verbose_name="Slug", unique="True")
post_highlighted = models.BooleanField(default=False)
def __str__(self):
return self.post_title
def get_absolute_url(self):
return reverse("singlepostManuscriptusView", kwargs={"slug": self.slug})
class Meta:
verbose_name = "Articolo"
verbose_name_plural = "Articoli"
Views.py
class ListPostGDV(ListView):
model = PostModel
template_name = "manuscriptus_home.html"
模板
{% for posts in object_list %}
<div id="news" class="container">
<div class="row">
<img class="img-fluid" src="{% static 'manuscriptus/img/demo_img.png' %}" alt="Header image">
</div>
<div class="row">
<div class="col-3">
<div class="row">
<small class="text-muted">Pubblicato il <strong>{{ posts.post_publishing_date|date }}</strong></small>
</div>
<div class="row">
{% for keyword in object_list.all %}
<p>{{ keyword }}</p>
{% endfor %}
</div>
</div>
<div class="col-9">
<div class="row">
<p class="h3"><a href="{{ posts.get_absolute_url }}">{{ posts.post_title }}</a></p>
</div>
<div class="row">
<p class="h5">{{ posts.post_short_description|safe|linebreaks }}</p>
</div>
</div>
</div>
</div>
{% empty %}
<div id="news" class="container">
<h1>Go to the admin panel and create your first post!</h1>
</div>
{% endfor %}
NB: I've used the generic detail views
在你的模板中你写:
<!-- this will iterate again over the <i>same</i> list -->
{% for keyword in <b>object_list.all</b> %}
<p>{{ keyword }}</p>
{% endfor %}
但是这里 object_list
是您的 QuerySet
篇文章。您调用 .all()
的事实仅意味着 for
循环将因此 再次 遍历所有 PostModel
(以及 .all()
用于明确表示您不进行过滤)。
如果您想遍历 post_keyconcept
,您需要调用 posts.post_keyconcept.all
:
{% for keyword in <b>posts.post_keyconcept.all</b> %}
<p>{{ keyword }}</p>
{% endfor %}
既然你想渲染所有 posts
的 key_concepts
,你最好在 ListView
中使用 .prefetch_related(..)
,这样 keywords
固定数量的查询,所以:
class ListPostGDV(ListView):
模型 = PostModel
queryset = PostModel.objects<b>.prefetch_related('post_keyconcept')</b>
# ...
Note: normally the names of models are singular and without the Model
suffix, so Post
instead of PostModel
, and KeyConcept
instead of KeyConceptModel
.
Note: since you iterate over object_list
(in the outer loop) the item is a single post, so I advice to name it post
, instead of posts
, since this otherwise only introduces confusion.
Note: you prefix all attributes with post_
which is a bit redundant. It also prevents making use of duck typing when for example two models have a name
attribute, and you want the function to be able to process both. Therefore I advise to remove the post_
prefix of the attributes.
我在 Django 模板中遇到了一个奇怪的问题。它是一个用于显示文章列表的模板,我会为他们中的每个人显示一个关键字列表,我称之为关键概念。
奇怪的是,显示的不是关键概念列表,而是使用该关键概念的文章列表。
在我的项目的E/R图表和模型及模板下方:
Models.py
class KeyConceptModel(models.Model):
concept_text = models.CharField(max_length=50)
def __str__(self):
return self.concept_text
def get_absolute_url(self):
return reverse("keyconceptManuscriptusView", kwargs={"pk": self.pk})
class Meta:
verbose_name = "Concetto chiave"
verbose_name_plural = "Concetti chiave"
class PostModel(models.Model):
post_title = models.CharField(max_length=70)
post_short_description = models.TextField(max_length=200)
post_contents = models.TextField()
post_publishing_date = models.DateTimeField(auto_now=False, auto_now_add=True)
post_author = models.ForeignKey(AuthorModel, on_delete=models.CASCADE)
post_keyconcept = models.ManyToManyField(KeyConceptModel)
slug = models.SlugField(verbose_name="Slug", unique="True")
post_highlighted = models.BooleanField(default=False)
def __str__(self):
return self.post_title
def get_absolute_url(self):
return reverse("singlepostManuscriptusView", kwargs={"slug": self.slug})
class Meta:
verbose_name = "Articolo"
verbose_name_plural = "Articoli"
Views.py
class ListPostGDV(ListView):
model = PostModel
template_name = "manuscriptus_home.html"
模板
{% for posts in object_list %}
<div id="news" class="container">
<div class="row">
<img class="img-fluid" src="{% static 'manuscriptus/img/demo_img.png' %}" alt="Header image">
</div>
<div class="row">
<div class="col-3">
<div class="row">
<small class="text-muted">Pubblicato il <strong>{{ posts.post_publishing_date|date }}</strong></small>
</div>
<div class="row">
{% for keyword in object_list.all %}
<p>{{ keyword }}</p>
{% endfor %}
</div>
</div>
<div class="col-9">
<div class="row">
<p class="h3"><a href="{{ posts.get_absolute_url }}">{{ posts.post_title }}</a></p>
</div>
<div class="row">
<p class="h5">{{ posts.post_short_description|safe|linebreaks }}</p>
</div>
</div>
</div>
</div>
{% empty %}
<div id="news" class="container">
<h1>Go to the admin panel and create your first post!</h1>
</div>
{% endfor %}
NB: I've used the generic detail views
在你的模板中你写:
<!-- this will iterate again over the <i>same</i> list -->
{% for keyword in <b>object_list.all</b> %}
<p>{{ keyword }}</p>
{% endfor %}
但是这里 object_list
是您的 QuerySet
篇文章。您调用 .all()
的事实仅意味着 for
循环将因此 再次 遍历所有 PostModel
(以及 .all()
用于明确表示您不进行过滤)。
如果您想遍历 post_keyconcept
,您需要调用 posts.post_keyconcept.all
:
{% for keyword in <b>posts.post_keyconcept.all</b> %}
<p>{{ keyword }}</p>
{% endfor %}
既然你想渲染所有 posts
的 key_concepts
,你最好在 ListView
中使用 .prefetch_related(..)
,这样 keywords
固定数量的查询,所以:
class ListPostGDV(ListView):
模型 = PostModel
queryset = PostModel.objects<b>.prefetch_related('post_keyconcept')</b>
# ...
Note: normally the names of models are singular and without the
Model
suffix, soPost
instead ofPostModel
, andKeyConcept
instead ofKeyConceptModel
.
Note: since you iterate over
object_list
(in the outer loop) the item is a single post, so I advice to name itpost
, instead ofposts
, since this otherwise only introduces confusion.
Note: you prefix all attributes with
post_
which is a bit redundant. It also prevents making use of duck typing when for example two models have aname
attribute, and you want the function to be able to process both. Therefore I advise to remove thepost_
prefix of the attributes.