2011-06-17 14 views
6

मैं वीडियो के बीच कई रिश्ते के लिए एक से एक के साथ एक बहुत ही सरल डेटामॉडल है और टिप्पणीdjango में n + 1 का चयन कैसे करें?

class Video(models.Model): 
    url = models.URLField(unique=True) 
    ..... 

class Comment(models.Model): 
    title = models.CharField(max_length=128) 
    video = models.ForeignKey('Video') 
     ..... 

मैं वीडियो के लिए क्वेरी और (सभी टिप्पणियों के साथ वीडियो) पूरी वस्तु ग्राफ हड़पने के लिए चाहते हैं। एसक्यूएल को देखते हुए, मुझे लगता है कि यह दो चयन करता है, एक वीडियो के लिए और टिप्पणियों के लिए एक। मैं उससे कैसे बचूं? मैं एक साथ जुड़ना चाहता हूं और सबकुछ एक साथ लेना चाहता हूं।

क्या यह django के साथ ऐसा करना संभव है?

उत्तर

0

देखें कि select related जिस तरह से आप इसकी अपेक्षा करते हैं, वह काम करता है, यह केवल इसके लिए बनाया गया था।

10

ForeignKey के लिए, आप selected_related() उपयोग कर सकते हैं:

Comment.objects.select_related('video').all() 

यह केवल एक ही प्रश्न उत्पन्न होगा, आप के साथ ही वीडियो के लिए coments सभा।

कुछ और जटिल (जैसे एम 2 एम) के लिए, आपको ऑप्टिमाइज़ेशन बनाने के लिए unjoinify जैसे बाहरी ऐप की आवश्यकता है लेकिन यह SQL क्वेरी का उपयोग करता है ताकि उन्हें ऑब्जेक्ट्स में वापस रखा जा सके।

  • django-queryset-transform:

    आप इस (मैं कर रहा हूँ) के साथ unconfortable हैं, तो आप कुछ विकल्प नहीं एक पूर्ण समाधान है, लेकिन मदद करता है

  • django-batch-select: roughtly एक select_related कि M2M और के साथ काम करता संबंधों रिवर्स ।
+0

मैं रिवर्स करना चाहता हूं, वीडियो से टिप्पणियां प्राप्त करना चाहता हूं। मैं वीडियो के लिए पूछना चाहता हूं लेकिन उन वीडियो के लिए सभी टिप्पणियां प्राप्त करें और परिणामस्वरूप एक एसक्यूएल स्टेटमेंट में: वीडियो वी से चुनें * v.id = c.video_id में शामिल हों जहां v.date> some_date। विचार सभी प्रश्नों और उनकी टिप्पणियों को एक प्रश्न में प्राप्त करना है। – bvk

+0

क्षमा करें मेरे एसक्यूएल स्टेटमेंट मैं उत्पादन करने के लिए देख रहा हूँ सही नहीं था। मैं निम्नलिखित जेनरेट करना चाहता हूं: v *id = c.id पर v.id> some_date पर वीडियो सी से टिप्पणी करें * में शामिल हों। अनिवार्य रूप से मैं सभी वीडियो और उनकी टिप्पणियां, यहां तक ​​कि टिप्पणियों के बिना वीडियो चाहता हूं। यह उदाहरण _Comment.objects.filter (video__title__starts_with = 'the') .select_related ('video')। सभी() _ बिना टिप्पणियों के वीडियो प्राप्त नहीं करेंगे। – bvk

+0

यही कारण है कि मैंने आपको अन्य उपकरणों के लिए एक लिंक दिया जैसे कि डीजेंगो-बैच-चयन जो आपके लिए यह कर सकता है: "अफसोसपूर्वक एक चयन_संबंधित जो एम 2 एम और रिवर रिलेशनशिप के साथ काम करता है"। –

1

आपको क्या करना है टिप्पणी पर select_related का उपयोग करना है।

कहते हैं कि तुम सभी वीडियो जिसका शीर्षक खोजने की जरूरत है की सुविधा देता है के साथ '' और यह

comments = Comment.objects.filter(video__title__starts_with='The') 
      .select_related('video').all() 

यह सभी टिप्पणियों और उस टिप्पणी के लिए उपयुक्त वीडियो वस्तु लोड होगा से संबंधित टिप्पणियों शुरू होता है। वीडियो पर फिर से चलाने के लिए आपको अभी भी वीडियो पर पिटोट करने की आवश्यकता होगी। स्मृति में पिवटिंग करने के लिए python itertools.groupby फ़ंक्शन का उपयोग करें।

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