25

के साथ select_related मेरे पास Django में दो मॉडल हैं। सबसे पहले नौकरी के कार्यों (पदों) की रिपोर्ट के पदानुक्रम में अन्य पदों के लिए पदानुक्रम है, और दूसरा लोग हैं और उनके पास कौन सा नौकरी कार्य है।रिवर्स विदेशी कुंजी

class PositionHierarchy(model.Model): 
    pcn = models.CharField(max_length=50) 
    title = models.CharField(max_length=100) 
    level = models.CharField(max_length=25) 
    report_to = models.ForeignKey('PositionHierachy', null=True) 


class Person(model.Model): 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 
    ... 
    position = models.ForeignKey(PositionHierarchy) 

जब मैं एक व्यक्ति रिकॉर्ड है और मैं व्यक्ति के प्रबंधक खोजना चाहते हैं, मुझे लगता है मैं (में शामिल होने और एक से बच सकते हैं

manager = person.position.report_to.person_set.all()[0] 
# Can't use .first() because we haven't upgraded to 1.6 yet 

करने के लिए मैं एक QuerySet के साथ लोगों को हो रही है, तो है, डेटाबेस के लिए दूसरी यात्रा) Person.objects.select_related('position', 'position__reports_to').filter(...) का उपयोग करने के लिए स्थिति और report_to के साथ, लेकिन व्यक्ति_सेट प्राप्त करने के लिए डेटाबेस में एक और यात्रा करने से बचने का कोई तरीका है? मैंने 'position__reports_to__person_set' या position__reports_to__person को select_related पर जोड़ने का प्रयास किया, लेकिन यह क्वेरी को बदलने में प्रतीत नहीं होता है। क्या यह prefetch_related है?

मैं एक कस्टम मैनेजर बनाना चाहता हूं ताकि जब मैं व्यक्ति रिकॉर्ड प्राप्त करने के लिए कोई प्रश्न पूछूं, तो मुझे डेटाबेस में और अधिक यात्रा के बिना अपनी स्थिति हिरासत और उनके प्रबंधक का व्यक्ति रिकॉर्ड भी मिलता है। यह वही है मैं अब तक है:

class PersonWithManagerManager(models.Manager): 
    def get_query_set(self): 
     qs = super(PersonWithManagerManager, self).get_query_set() 
     return qs.select_related(
      'position', 
      'position__reports_to', 
     ).prefetch_related(
     ) 
+0

शायद लिखने में कोई त्रुटि है, लेकिन यह 'get_queryset()', नहीं 'get_query_set' होना चाहिए। – Paolo

+1

@ पाओलो यह Django 1.5 में 'get_query_set' था। –

उत्तर

25

हाँ, कि क्या prefetch_related() के लिए है। इसके लिए एक अतिरिक्त क्वेरी की आवश्यकता होगी, लेकिन विचार यह है कि यह Person प्रति बार एक बार की बजाय सभी संबंधित जानकारी प्राप्त करेगा।

आपके मामले में:

qs.select_related('position__report_to') 
    .prefetch_related('position__report_to__person_set') 

दो प्रश्नों, मूल प्रश्न सेट में Persons की संख्या की परवाह किए बिना किया जा सकेगा।

documentation से इस उदाहरण की तुलना करें:

>>> Restaurant.objects.select_related('best_pizza') 
         .prefetch_related('best_pizza__toppings') 
संबंधित मुद्दे