2013-10-22 10 views
7

कभी-कभी यह django टेम्पलेट में select_related का उपयोग करने के लिए समझ में आता है। उदाहरण के लिए, मैं एक वर्ग का विस्तार DetailViewdjango टेम्पलेट में चयन_संबंधित

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) 

एचटीएमएल टेम्पलेट तो है

{{ 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 पार्ट्स में शामिल होने वाली हर विदेशी कुंजी के साथ जुड़ रहा है। क्या वांछित संबंधित तालिकाओं तक इसे सीमित करने का कोई तरीका है। पायथन में यह सिर्फ है:

Part.objects.select_related('manufacturer').filter(car=car) 

क्या यह टेम्पलेट में किया जा सकता है?

नोट: मैं जानता हूँ कि मैं 'कार' और select_related('manufacturer') फिल्टर पर साथ 'भागों' के लिए एक के लिए एक संदर्भ वापस लौट कर बहुत आसानी से ध्यान में रखते हुए ऐसा कर सकते हैं, लेकिन यह 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 

हालांकि, इस टेम्पलेट इस दृष्टिकोण के अधिक विशिष्ट के रूप में यह अब car.part_set.all बजाय 'भागों' संदर्भ का उपयोग करने की आवश्यकता होगी की आवश्यकता है। साथ ही, यह दृश्य पहली जगह बनाने के लिए बस और अधिक काम है।

उत्तर

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

संबंधित मुद्दे