2013-10-22 17 views
7

場合によっては、djangoテンプレートでselect_relatedを使用することが理にかなっています。例えば、私は以下の不自然なモデルに基づいてDetailViewdjango select_related in template

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サブセクションと比較してかなりコードがあります。クラス私は上記で使用しました。このような何か:それは今car.part_set.allではなく、「部」コンテキストを使用する必要がありますよう

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 

しかし、これは、このビューに、より具体的には、テンプレートが必要です。また、最初にこのビューを作成するだけです。

答えて

18

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 %} 
+0

、私は実際にあなたがモデルにテンプレートとpart_setのメソッドにアクセスすることができ実現しませんでした。ありがとう。 – dpwrussell

関連する問題