我正在尝试在模板中显示通过Foreign Key field
连接的django对象。
我试图举一个简单的例子,以说明我想使用accordion html
从模板中得到什么。
我的Django模型:
class Grandparent(models.Model):
name = models.CharField(...)
age = models.IntegerField(...)
def __str__(self):
return f"{self.name} : {self.age}"
class Parent(models.Model):
name = models.CharField(...)
age = models.IntegerField(...)
grandparent = models.ForeignKey(Grandparent, related_name='grandparent')
def __str__(self):
return f"{self.name} : {self.age}"
class Child(models.Model):
name = models.CharField(...)
age = models.IntegerField(...)
parent = models.ForeignKey(Parent, related_name='parent')
def __str__(self):
return f"{self.name} : {self.age}"
如您所见,孩子取决于父母,而父母取决于祖父母。
我的html模板:
现在,我想在HTML模板中显示类似的内容:
所以我的HTML如下所示,我并没有克服想要的东西:
{% for grandparent in grandparent_list %}
<div class="accordion-publication panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<div class="panel-primary">
<div class="panel-heading" role="button" id="head_0" data-toggle="collapse">
<span>{{ grandparent }}</span>
</div>
{% for parent in parent_list %}
<div class="panel-collapse collapse in" role="tabpanel" aria-expanded="true">
<div class="panel-body">
<div class="panel panel-default">
<div class="panel-heading collapsed" role="button" data-toggle="collapse" aria-expanded="true">
<span class="panel-title">{{ parent }}</span>
</div>
<div class="panel-collapse collapse in" role="tabpanel" aria-labelledby="head_0">
<div class="panel-body">
{% for child in child_list %}
<table class="table table-condensed">
<tbody>
<tr>
<td class="col-md-1"> {{ child }}</td>
</tr>
</tbody>
</table>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
此HTML有点通用,但是为了显示for each grandparent
显示each parents associated
然后显示each child associated to each parent
,我并没有克服获取每个级别和子级别之间的关系的要求。
我的django视图:
我在django视图中的班级是这样的:
def get_context_data(self, **kwargs):
self.count_number_document()
self.flag_publication()
kwargs['child_list'] = Child.objects.all().order_by('parent__grandparent__name')
kwargs['parent_list'] = Parent.objects.all().order_by('name')
kwargs['grandparent_list'] = Grandparent.objects.all()
return super(MyClassView, self).get_context_data(**kwargs)
答案 0 :(得分:2)
感谢阿拉斯代尔的回答,我找到了解决方法。
首先,我必须这样定义我的模型(related_name
调整):
class Grandparent(models.Model):
name = models.CharField(...)
age = models.IntegerField(...)
def __str__(self):
return f"{self.name} : {self.age}"
class Parent(models.Model):
name = models.CharField(...)
age = models.IntegerField(...)
grandparent = models.ForeignKey(Grandparent, related_name='parents')
def __str__(self):
return f"{self.name} : {self.age}"
class Child(models.Model):
name = models.CharField(...)
age = models.IntegerField(...)
parent = models.ForeignKey(Parent, related_name='children')
def __str__(self):
return f"{self.name} : {self.age}"
然后,在我的view.py文件中,只需设置:
kwargs['grandparent_list'] = Grandparent.objects.all().order_by('name')
最后在我的html模板中:
{% for grandparent in grandparent_list %}
<div class="accordion-publication panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<div class="panel-primary">
<div class="panel-heading" role="button" id="head_0" data-toggle="collapse">
<span>{{ grandparent }}</span>
</div>
{% for parent in grandparent.parents.all %}
<div class="panel-collapse collapse in" role="tabpanel" aria-expanded="true">
<div class="panel-body">
<div class="panel panel-default">
<div class="panel-heading collapsed" role="button" data-toggle="collapse" aria-expanded="true">
<span class="panel-title">{{ parent }}</span>
</div>
<div class="panel-collapse collapse in" role="tabpanel" aria-labelledby="head_0">
<div class="panel-body">
{% for child in parent.children.all %}
<table class="table table-condensed">
<tbody>
<tr>
<td class="col-md-1"> {{ child }}</td>
</tr>
</tbody>
</table>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
答案 1 :(得分:0)
首先,在所有相关名称上使用“ children”,以便grandparent.children.all()会为grand parent的所有子代(例如Parent实例)提供。父类和子类也是如此。
进入视图,仅在上下文中发送祖父母。但是,等等,如果您访问子代及其子代,这将导致N + 1个查询。 因此,在发送祖父母时使用预取。
grandparents = Grandparent.objects.all().prefetch_related(Prefetch('children', queryset=Parent.objects.all().prefetch_related('children')))