将视图中的信息与HTML页面中的特定记录链接

时间:2018-07-01 10:11:32

标签: python django

我有三种型号:

汽车(包含汽车记录):

name = models.CharField(max_length=255)

样本记录:

  • 汽车A
  • 汽车B
  • 汽车C

功能(包含可能会感兴趣的具有不同功能的列表)

name = models.CharField(max_length=255)
primary_feature = models.BooleanField()

样本记录:

  • 颜色,primary_feature = true
  • 窗户数,primary_feature = false
  • 所有者,primary_feature = true

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 | ???       | ???

我应该如何处理?

1 个答案:

答案 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>