2009-07-10 16 views
5

मैं रिकार्ड समय में एक आंतरिक वेबसाइट को कोड करते समय पूरे दिन Django पर डोलिंग कर रहा हूं, लेकिन अब मैं देख रहा हूं कि मॉडल में मेरे विदेशी के साथ कुछ अक्षम है।django विदेशीकी फ़ील्ड से बहुत सारे प्रश्न

मेरे पास एक मॉडल है जिसमें 6 विदेशीके हैं, जो मूल रूप से लुकअप टेबल हैं। जब मैं सभी ऑब्जेक्ट्स से पूछता हूं और उन्हें टेम्पलेट में प्रदर्शित करता हूं, तो यह प्रति आइटम लगभग 10 प्रश्न चला रहा है। यहां कुछ कोड दिया गया है, जो इसे बेहतर समझा जाना चाहिए:

class Website(models.Model): 
    domain_name = models.CharField(max_length=100) 
    registrant = models.ForeignKey('Registrant') 
    account = models.ForeignKey('Account') 
    registrar = models.ForeignKey('Registrar') 
    server = models.ForeignKey('Server', related_name='server') 
    host = models.ForeignKey('Host') 
    target_server = models.ForeignKey('Server', related_name='target') 

class Registrant(models.Model): 
    name = models.CharField(max_length=100) 

... और 5 और सरल टेबल। वहाँ 155 वेबसाइट रिकॉर्ड हैं, और ध्यान में रखते हुए मैं उपयोग कर रहा हूँ:

Website.objects.all() 

यह 1544 प्रश्नों को क्रियान्वित समाप्त होता है। टेम्पलेट में, मैं, विदेशी क्षेत्रों के सभी का उपयोग कर रहा में के रूप में:

<span class="value">Registrant:</span> <a href="/filter/registrant/{{ website.registrant.id }}">{{ website.registrant.name }}</a><br /> 

तो मैं जानता हूँ कि यह प्रश्नों का एक बहुत चलाने के लिए जा रहा है ... लेकिन ऐसा लगता है जैसे यह अत्यधिक है। क्या यह सामान्य है? क्या मुझे ऐसा नहीं करना चाहिए?

मैं Django के लिए काफी नया हूं, इसलिए उम्मीद है कि मैं बस कुछ बेवकूफ कर रहा हूं। यह निश्चित रूप से एक सुंदर अद्भुत ढांचा है।

उत्तर

5

आपको select_related function का उपयोग करना चाहिए, उदा।

Website.objects.select_related() 

, जिससे कि वह एक में शामिल होने और उन विदेशी कुंजी के सभी का पालन करें जब क्वेरी मांग पर उन्हें लोड के रूप में वे उपयोग किया जाता है के बजाय किया जाता है क्या करेंगे। Django डेटाबेस से डेटा को आलसी लोड करता है, इसलिए डिफ़ॉल्ट रूप से आपको निम्न व्यवहार

# one database query 
website = Website.objects.get(id=123) 

# first time account is referenced, so another query 
print website.account.username 

# account has already been loaded, so no new query 
print website.account.email_address 

# first time registrar is referenced, so another query 
print website.registrar.name 

और इसी तरह से मिलता है। यदि आप चयनित संबंधित का उपयोग करते हैं, तो दृश्यों के पीछे एक जॉइन किया जाता है और इन सभी विदेशी कुंजियों का स्वचालित रूप से पालन किया जाता है और पहली क्वेरी पर लोड किया जाता है, इसलिए केवल एक डेटाबेस क्वेरी होती है। तो उपर्युक्त उदाहरण में, आपको

# one database query with a join and all foreign keys followed 
website = Website.objects.select_related().get(id=123) 

# no additional query is needed because the data is already loaded 
print website.account.username 
print website.account.email_address 
print website.registrar.name 
+0

धन्यवाद! यह निश्चित रूप से उस समारोह को समझने के लिए बहुत समझ में आता है। अब यह 9 प्रश्न चल रहा है। चूंकि टेबल छोटी हैं, मुझे परवाह नहीं है कि यह सभी डेटा लोड कर रहा है (और स्पष्ट रूप से यह बेहतर तरीका है)। –

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