我有三种型号:
汽车(包含汽车记录):
name = models.CharField(max_length=255)
样本记录:
功能(包含可能会感兴趣的具有不同功能的列表)
name = models.CharField(max_length=255)
primary_feature = models.BooleanField()
样本记录:
CarFeatures(包含功能及其值):
car = models.ForeignKey(Car, on_delete=models.CASCADE)
feature = models.ForeignKey(Feature, on_delete=models.CASCADE)
value = models.CharField(max_length=255)
样本记录:
Car | Feature | Value ========================== Car A | color | green Car A | owner | Alice Car B | color | blue Car C | windows | 6
您可能想知道这些模型的结构,但是我在这里简化。因此,让我们假设这些模型有意义。
现在的问题是:我想列出所有汽车的清单,然后在表中显示特定特征(那些是主要特征)。所以我的最终目标是得到这个:
Car | Color | Owner ============================= Car A | green | Alice Car B | blue | unknown Car C | unknown | unknown
需要注意的是,并非所有功能都适用于所有汽车。
问题是:如果我想获得包含所有所有汽车且仅具有特定功能的列表,正确的解决方法是什么?
在视图中,我有这个:
cars = Car.objects.all()
features = Feature.objects.filter(primary_feature=True)
car_features = CarFeature.objects.filter(feature__primary_feature=True)
然后在HTML页面上执行此操作:
<table>
<tr>
<th>Car</th>
{% foreach feature in features %}
<th>{{ feature.name }}</th>
{% endforeach %}
</tr>
{% foreach car in cars %}
<tr>
<td>{{ car.name }}</td>
{% foreach feature in features %}
<td>??? How do I get the right value here??</td>
{% endforeach %}
</tr>
{% endforeach %}
</table>
这就是我得到的:
Car | Color | Owner ============================= Car A | ??? | ??? Car B | ??? | ??? Car C | ??? | ???
我应该如何处理?
答案 0 :(得分:1)
如果您还没有碰到它,您可能会发现ListView
对于在表中显示对象很有用。例如,您可以这样做;
CarsList(ListView):
model = Car
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['features'] = Feature.objects.filter(
primary_feature=True
)
return context
然后在您的模板中添加
<table>
<tr>
<th>Car</th>
{% for feature in features %}
<th>{{ feature.name }}</th>
{% endfor %}
</tr>
{% for car in object_list %}
<tr>
<td>{{ car.name }}</td>
{% for car_feature in car.carfeatures_set.all %}
<td>{{ car_feature.feature }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
现在,您已经问过如何获得具有特定功能的所有汽车。这将涉及对与您想要的CarFeature
相关的Feature
对象的反向查找。
例如;
special_feature = Features.objects.get(name='Special')
car_features = special_feature.carfeatures_set.all()
# Then all cars with `special_feature` is
special_cars = car_features.values('car')
或在模板中
{% for car_feature in car_features %}
{{ car_feature.car.name }}
{% endfor %}
您可能还会发现通读多对一关系文档会有所帮助; https://docs.djangoproject.com/en/2.0/topics/db/examples/many_to_one/
要显示所有具有相关主要功能的汽车,您需要查询CarFeatures
表,类似于;
def get_context_data(self, **kwargs):
context = super(CarList, self).get_context_data(**kwargs)
cars = list()
for obj in Car.objects.all():
cars.append(
(obj.name,
obj.carfeatures_set.filter(feature__primary_feature=True))
)
context['cars'] = cars
return context
模板中的内容如下;
<h1>Cars</h1>
<ul>
{% for car, carfeatures in cars %}
<li>
{{ car }}
<ul>
{% for carfeature in carfeatures %}
<li>{{ carfeature.feature.name }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>