Django:在views.py中使用向后关系

时间:2018-02-19 16:45:45

标签: python django django-views foreign-keys

我试图将一个对象传递给我的HTML模板,该模板由父对象和与之相关的所有子对象组成。例如:

示范庭:

class Chamber(models.Model):
    chamber_name = models.CharField(max_length=100)
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)

有ChamberProperty:

class ChamberProperty(models.Model):
    chamber = models.ForeignKey(Chamber, on_delete=models.CASCADE)
    property_name = models.CharField(max_length=50)
    property_value = models.CharField(max_length=100)
    user_defined = models.BooleanField(default=True)

它们是两个独立的模型,因为客户可以根据需要添加任意数量的属性。

在我的views.py

class ChambersView(generic.DetailView):
    template_name = 'pages/chambers.html'

    def get(self, request):
        user = User.objects.get(username=request.user)
        customer = Customer.objects.get(user=user)
        chambers_list = list(Chamber.objects.filter(customer=customer))

        try:
            chamber_properties = list(ChamberProperty.objects.filter(chamber__in=chambers_list).order_by('id'))
        except:
            chamber_properties = "No properties"

        form = ChambersFilterForm(request=request)
        return render(request, self.template_name, {'filter_form':form, 'chambers_list': chambers_list, 'chamber_properties': chamber_properties})

现在,这确实让我得到了所有房间的清单,以及所有房间属性的清单。除非他们彼此没有联系。我不确定如何构建相关对象列表。我刚才读到了关于倒退的关系,但我似乎并不知道如何使用它们。

我尝试了以下内容:

chambers_and_props = Chamber.chamberproperty_set.all()

我收到以下错误:

AttributeError: 'ReverseManyToOneDescriptor' object has no attribute 'all'

所以我不太确定如何使用它。我看到的线程提到Django中的一个关系会自动在ForeignKeys上添加一个反向,并且使用parent.child_set.all()并且child更低。{/ p>

我得到一个ReverserManyToOneDescriptor对象,但不知道如何将其转换为可以传递给我的HTML模板的可用列表。

关于我做错什么的任何想法?

2 个答案:

答案 0 :(得分:2)

您的查询无效,因为您尚未指定哪个商会要获得向后关系。

然而,这不是正确的方法。大概你想要ChamberProperty,所​​以你可以在模板中针对每个Chamber列出它们。因此,您应该遵循模板中的关系 - 根本不需要在视图中单独查询ChamberProperty。

{% for chamber in chamber_list %}
  {{ chamber.chamber_name }}
  {% for property in chamber.chamberproperty_set.all %}
    {{ property.property_name }} : {{ property.property_value }}
  {% endfor %}
{% endfor %}

答案 1 :(得分:1)

您收到错误是因为您在模型Chamber.chamberproperty_set上尝试Chamber。它适用于单个chamber实例:

您可以在视图中执行此操作:

for chamber in chambers_list
    properties = chamber.chamberproperty_set.all()

或在模板中:

{% for chamber in chambers_list %}
    {{ chamber }}
    {% for property in chamber.chamberproperty_set.all %}
    {{ property }}
{% endfor %}

然后,在您的视图中,您可以使用prefetch_related来减少SQL查询的数量:

chambers_list = Chamber.objects.filter(customer=customer).prefetch_related('chamberproperty_set')