2013-10-22 27 views
7

Bazen bir django şablonunda select_related kullanımı mantıklı. Örneğin, ben şu yapmacık modele dayanarak DetailViewdjango select_related şablon

class DemoCarView(DetailView): 
    model = Car 

uzanan bir sınıf var demek

# 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 şablonu daha sonra

Bu araba almak için mükemmel çalışıyor
{{ car.name }} 
<ul> 
{% for part in car.part_set.all %} 
    <li>{{ part.name }} - {{ part.manufacturer.name }} </li> 
{% endfor %} 
</ul> 

, onu oluşturan parçalar ve bu parçaların üreticileri. Ancak, bunu yapmak için 2 + number_of_parts SQL sorgularını kullanacaktır. Kolayca düzeltildi:

{{ car.name }} 
<ul> 
{% for part in car.part_set.select_related.all %} 
    <li>{{ part.name }} - {{ part.manufacturer.name }} </li> 
{% endfor %} 
</ul> 

Şimdi en iyi 2 sorgu çalıştırılıyor. Ancak, select_related, Parçaları sahip olduğu her Yabancı Anahtarla birleştiriyor. Bunu sadece istenen tablolarla sınırlamak için bir yol var mı. Python'da sadece şu: Şablonda yapılabilir mi?

Not: Filtre üzerinde select_related('manufacturer') ile 'araba' ve 'parçalar' için bir bağlam döndürerek bu işlemi çok kolay bir şekilde yapabileceğimi biliyorum, ancak DetailView alt bölümüne göre biraz daha fazla kod var. Yukarıda kullandığım sınıf. Böyle bir şey: o şimdi car.part_set.all yerine 'parçaları' bağlamı kullanmanız gerekecektir olarak

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 

Ancak bu Bu görüşe daha spesifik olması şablonu gerektirir. Ayrıca, bu görüşü ilk etapta yapmak daha basit bir iş.

cevap

18

Car modelinde basit bir yöntem nasıl olur?

class Car(models.Model): 
    ... 
    def parts_with_manufacturers(self): 
     return self.part_set.select_related('manufacturer') 

ve güzel bir çözüm daha sonra

{% for part in car.parts_with_manufacturers %} 
    <li>{{ part.name }} - {{ part.manufacturer.name }} </li> 
{% endfor %} 
+0

, aslında modeldeki şablonu ve part_set yöntemleri erişebilecek farkında değildi. Teşekkürler. – dpwrussell

İlgili konular