[英]django select_related in template
有时在Django模板中使用select_related是有意义的。 例如,假设我有一个扩展DetailView的类
class DemoCarView(DetailView):
model = Car
基于以下人为模型
# Cars
class Car(models.Model):
name = models.CharField(max_length=32)
# Manufacturers
class Manufacturer(models.Model):
name = models.CharField(max_length=32)
# Parts
class Part(models.Model):
name = models.CharField(max_length=32)
car = models.ForeignKey(Car)
manufacturer = models.ForeignKey(Manufacturer)
然后是html模板
{{ car.name }}
<ul>
{% for part in car.part_set.all %}
<li>{{ part.name }} - {{ part.manufacturer.name }} </li>
{% endfor %}
</ul>
这非常适合获得汽车,组成汽车的零件以及这些零件的制造商。 但是,这将使用2 + number_of_parts个SQL查询来执行此操作。 像这样轻松修复:
{{ car.name }}
<ul>
{% for part in car.part_set.select_related.all %}
<li>{{ part.name }} - {{ part.manufacturer.name }} </li>
{% endfor %}
</ul>
现在运行2个查询中的最优查询。 但是, select_related
将零件与它具有的每个外键连接在一起。 有没有一种方法可以将其限制为仅所需的相关表。 在Python中,它只是:
Part.objects.select_related('manufacturer').filter(car=car)
可以在模板中完成吗?
注意:我知道我可以通过在过滤器上通过select_related('manufacturer')
返回一个'car'上下文和一个'parts'上下文来非常轻松地在视图中执行此操作,但是与DetailView子控件相比,它的代码要多得多我在上面使用过的类。 像这样:
class DemoCarViewPreload(TemplateView):
template_name = 'demo/car_detail_preload.html'
def get_context_data(self, **kwargs):
context = super(DemoCarViewPreload, self).get_context_data(**kwargs)
car = Car.objects.get(pk=kwargs.get('pk'))
context['car'] = car
context['parts'] = Part.objects.select_related('manufacturer').filter(car=car)
return context
但是,这要求模板对该视图更加特定,因为它现在需要使用'parts'上下文而不是car.part_set.all
。 此外,首先要制作此视图只是要做更多的工作。
Car
模型上的简单方法怎么样?
class Car(models.Model):
...
def parts_with_manufacturers(self):
return self.part_set.select_related('manufacturer')
然后
{% for part in car.parts_with_manufacturers %}
<li>{{ part.name }} - {{ part.manufacturer.name }} </li>
{% endfor %}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.