2010-05-14 20 views
12

मैं अपने Django कोड में 2 मॉडल:किसी एक क्वेरी में विदेशी कुंजी वस्तुओं मिलता है - Django

class ModelA(models.Model): 
    name = models.CharField(max_length=255) 
    description = models.CharField(max_length=255) 
    created_by = models.ForeignKey(User) 

class ModelB(models.Model): 
    category = models.CharField(max_length=255) 
    modela_link = models.ForeignKey(ModelA, 'modelb_link') 
    functions = models.CharField(max_length=255) 
    created_by = models.ForeignKey(User) 

कहो ModelA 100 रिकॉर्ड है, जो सभी के या ModelB

को

लिंक नहीं हो सकता है हो सकता है अब कहते हैं कि मैं ModelB

से डेटा के साथ हर ModelA रिकॉर्ड की एक सूची प्राप्त करना चाहते हैं

मुझे क्या करना होगा:

list_a = ModelA.objects.all() 

फिर ModelB के लिए डेटा मैं होता

for i in list_a: 
    i.additional_data = i.modelb_link.all() 

हालांकि इस मैं के प्रत्येक उदाहरण पर एक प्रश्न चलाता है करने के लिए मिलता है। इस प्रकार चलाने के लिए 101 प्रश्न बनाते हैं।

वहाँ सब सिर्फ 1 क्वेरी में इस चलाने का कोई तरीका है। या कम से कम 101 प्रश्नों से कम।

मैं ModelA.objects.select_related().all() में डालने की कोशिश की है, लेकिन यह कोई असर नहीं लगता था।

धन्यवाद

उत्तर

7

Ofri कहते हैं, select_related केवल आगे संबंधों पर काम करता है, लोगों को रिवर्स नहीं।

कोई अंतर्निहित तरीका स्वचालित रूप से Django में संबंधों को उल्टा पालन करें, लेकिन एक तकनीक के लिए my blog post देखें कि यह काफी कुशलता से ऐसा करने के लिए करने के लिए नहीं है। ताकि आप n + 1 के बजाय 2 प्रश्नों में यह कर सकते हैं - मूल विचार हर आइटम के लिए सभी संबंधित वस्तुओं को एक बार में प्राप्त करने के लिए, तो उन्हें अपने संबंधित आइटम के साथ मैन्युअल रूप से जोड़ते है।

2

Django ORM एक अच्छी बात है लेकिन कुछ कुछ बातें मैन्युअल रूप से करना बेहतर है। आप कनेक्शन कर्सर आयात और एक क्वेरी में कच्चे एसक्यूएल निष्पादित कर सकते हैं।

from django.db import connection 
cur=connection.cursor() 
cur.execute(query) 
rows = cur.fetchall() 

आपकी क्वेरी (MySQL के लिए ) की तरह दिखना चाहिए

SELECT * FROM appname_modela INNER JOIN appname_modelb ON appname_modela.id=appname_modelb.modela_link_id 
+0

मुझे पता है कि जब कच्चे एसक्यूएल का उपयोग कर आप नहीं मिलता है एक वस्तु तो आप किसी भी तरह से एक Django वस्तु में परिणाम कन्वर्ट करने के लिए – John

1

कारण .select_related() काम नहीं किया, कि .select_related() विदेशी कुंजी का पालन करने के लिए किया जाता है। आपके मॉडल ए में मॉडलबी के लिए कोई विदेशी कुंजी नहीं है। इसका मॉडलबी जिसमें मॉडल ए के लिए एक विदेशी कुंजी है। (ताकि एक ModelA उदाहरण इसे से संबंधित कई ModelB उदाहरण हो सकते हैं)।

आप इस का उपयोग 2 प्रश्नों में यह करने के लिए कर सकता है, और अजगर कोड का एक सा:

list_b = ModelB.objects.all() 
list_a = ModelA.objects.all() 
for a in list_a: 
    a.additional_data = [b for b in list_b if b.modela_link_id==a.id] 
+1

इस के लिए धन्यवाद का पता चलेगा लौट आए। क्या इससे कोई प्रदर्शन समस्या है – John

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