首页 > 解决方案 > 通过 DetailView 访问子模型?

问题描述

我有两个模型农民和动物。Animal(s) 通过 ForeignKey 与 Farmer(s) 相关联。

正如您在模板中看到的那样,我想展示一个农民和他的相关动物。我的模板显示了名字、姓氏和城市,正确地,唯一缺少的是来自子模型的相关动物。

在其他项目中,我使用“{% for item in ParentModel.ChildModel_set.all %}”来访问子模型,不幸的是这次它不起作用。

那是因为我使用了 DetailView 吗?

模型.py

class Farmer(models.Model):
    first_name = models.CharField(max_length=40)
    last_name = models.CharField(max_length=40)
    city = models.CharField(max_length=40)

    objects = FarmerManager() # --- link to Manager

    def __str__(self):
        return self.last_name

    def get_absolute_url(self):
        return reverse("datainput:farmer_detail", kwargs={"id": self.id})

class Animal(models.Model):
    name = models.CharField(max_length=40)
    weight = models.DecimalField(max_digits=5, decimal_places=2)
    species = models.ForeignKey('Species', on_delete=models.CASCADE)
    farmer = models.ForeignKey('Farmer', related_name='farmername', on_delete=models.CASCADE)

    objects = AnimalManager() # --- link to Manager

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse("datainput:animal_detail", kwargs={"id": self.id})

视图.py

class FarmerDetailView(DetailView):
    template_name ="datainput/farmer_detail.html"
    queryset = Farmer.objects.all()

    def get_object(self):
        some_id = self.kwargs.get("id")
        return get_object_or_404(Farmer, id=some_id)

网址.py

<...>
    path('farmer/<int:id>/', FarmerDetailView.as_view(), name='farmer_detail'),
<...>

farmer_detail.html

<...>    
<div class="row" id="p1">
        <div class="col-6 offset-md-3">
            <p> Bauer {{ farmer.first_name }}  {{ farmer.last_name }}</p>  in {{ farmer.city }} 
            {% for animals in farmer.animal_set.all %}
            <p>  {{ animals }} </p>
            {% endfor %}
        </div>

    </div>
<...>   

标签: djangodjango-modelsdjango-templatesdjango-views

解决方案


那是因为我用了一个DetailView

,那是因为你用related_name错了方法。

related_name[Django-doc]ForeignKey[Django-doc]反向关系的名称:

用于从相关对象返回到此对象的关系的名称。related_query_name它也是(用于目标模型的反向过滤器名称的名称)的默认值。

这意味着如果 anAnimal有一个到 的外键Farmer,则related_name应该包含从 theFarmer到它Animal的 s 的关系名称。farmername这里不是一个好主意。

您可以将其重命名为:

class Animal(models.Model):
    # ...
    farmer = models.ForeignKey('Farmer', related_name='animals', on_delete=models.CASCADE)
    # ...

在您的模板中,您可以遍历.animals

{% for animals in farmer.animals.all %}
<p>  {{ animals }} </p>
{% endfor %}

或者您可以省略指定related_name. Django然后自动使用modelname_set,所以这里是animal_set

class Animal(models.Model):
    # ...
    farmer = models.ForeignKey('Farmer', on_delete=models.CASCADE)
    # ...

然后animal_set像以前一样使用:

{% for animals in farmer.animal_set.all %}
<p>  {{ animals }} </p>
{% endfor %}

推荐阅读