2008-11-23 27 views
11

मेरे विशिष्ट मामले में, मेरे पास दो प्रकार के "संदेश" हैं जिन्हें मुझे पुनः प्राप्त करने और अंकन करने की आवश्यकता है।django का उपयोग करके मैं अलग-अलग मॉडलों से दो प्रश्नों को एक प्रश्न में कैसे जोड़ सकता हूं?

के विवरण को छोड़ देते हैं, और बस का कहना है कि पहली तरह एक मॉडल Msg1 कहा जाता है और अन्य में कहा जाता है Msg2

इन दो मॉडलों के क्षेत्र पूरी तरह से अलग, केवल फ़ील्ड के लिए आम हैं कर रहे हैं दो मॉडल "दिनांक" और "शीर्षक" (और निश्चित रूप से, आईडी) हैं।

मैं Msg1.objects.all() और Msg2.objects.all() प्राप्त कर सकता हूं, लेकिन क्या मैं इन दो प्रश्नों को एक प्रश्न में जोड़ सकता हूं, इसे आज तक क्रमबद्ध कर सकता हूं, और इसे पृष्ठबद्ध कर सकता हूं?

मुझे क्वेरी की आलसी प्रकृति को संरक्षित करने की आवश्यकता है।

मामूली समाधान list(query) दोनों प्रश्नों के लिए है और उन्हें एक पायथन सूची में गठबंधन करें। लेकिन यह स्पष्ट कारणों से अक्षम है।

मैंने मॉडल और डीपी-एपीआई पर django संदर्भों को देखा, लेकिन ऐसा नहीं लगता है कि विभिन्न मॉडलों/तालिकाओं के प्रश्नों को एक में जोड़ना एक तरीका है।

+0

"स्पष्ट कारणों से अक्षम" वास्तव में? क्या आपके पास मेट्रिक्स है? मैं पूछता हूं क्योंकि कोई स्पष्ट कारण नहीं है कि यह अक्षम क्यों होगा। –

+0

मुझे लगता है क्योंकि एक बार जब आप सूची (क्वेरी) सूचीबद्ध करते हैं तो यह सभी परिणाम प्राप्त करता है, और वह जितना संभव हो सके इसे छोड़ना चाहता है। –

+0

अक्षम है क्योंकि यह सभी वस्तुओं के लिए डेटा बेस हिट करता है, (1000 हो सकता है) जबकि केवल 20 प्रति पृष्ठ प्रदर्शित करता है .. – hasen

उत्तर

11

मैं सुझाव है कि आप Model inheritance का उपयोग करें।

एक आधार मॉडल बनाएं जिसमें दिनांक और शीर्षक शामिल है। वर्णित के रूप में Subclass Msg1 और Msg2 इसे बंद करें। आधार मॉडल का उपयोग करके अपने सभी प्रश्नों (एक पृष्ठ को भरने के लिए) करें और फिर आखिरी पल में व्युत्पन्न प्रकार पर स्विच करें।

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

+1

क्या होगा यदि मेरा बेस क्लास अमूर्त है? क्या आप कुछ कोड उदाहरण दिखा सकते हैं? –

2

"इन दो प्रश्नों को एक प्रश्न में गठबंधन करें, इसे तिथि से क्रमबद्ध करें, और इसे पृष्ठबद्ध करें?"

  1. यह एसक्यूएल संघ है। Django ORM छोड़ें और एक एसक्यूएल संघ का उपयोग करें। यह शानदार रूप से तेज़ नहीं है क्योंकि एसक्यूएल को एक अस्थायी परिणाम बनाना है, जो इसे पसंद करता है।

  2. अस्थायी परिणाम बनाएं, जिसे सॉर्ट किया जा सकता है। चूंकि एक सूची में एक प्रकार की विधि है, इसलिए आपको दो परिणामों को एक सूची में विलय करना होगा।

  3. एक मर्ज एल्गोरिदम लिखें जो दो क्वेरी सेट स्वीकार करता है, परिणामों को पगेट करता है।


संपादित करें। यहां मर्ज एल्गोरिदम है।

def merge(qs1, qs2): 
    iqs1= iter(qs1) 
    iqs2= iter(qs2) 
    k1= iqs1.next() 
    k2= iqs2.next() 
    k1_data, k2_data = True, True 
    while k1_data or k2_data: 
     if not k2_data: 
      yield k1 
      try: 
       k1= iqs1.next() 
      except StopIteration: 
       k1_data= False 
     elif not k1_data: 
      yield k2 
      try: 
       k2= iqs2.next() 
      except StopIteration: 
       k2_data= False 
     elif k1.key <= k2.key: 
      yield k1 
      try: 
       k1= iqs1.next() 
      except StopIteration: 
       k1_data= False 
     elif k2.key < k1.key: # or define __cmp__. 
      yield k2 
      try: 
       k2= iqs2.next() 
      except StopIteration: 
       k2_data= False 
     else: 
      raise Exception("Wow...") 

आप पृष्ठांकन में गुना कर सकते हैं:

def paginate(qs1, qs2, start=0, size=20): 
    count= 0 
    for row in merge(qs1, qs2): 
     if start <= count < start+size: 
      yield row 
     count += 1 
     if count == start+size: 
      break 
+0

यदि आप इस पथ का पालन करना चाहते हैं, तो आप एसक्यूएल निर्देश में यूनियन से पहले इस तरह का प्रदर्शन करना चाहते हैं (क्योंकि एसक्यूएल क्रम में तेजी लाने के लिए इंडेक्स का उपयोग कर सकता है) और उम्मीद है कि आप यूनियन से पहले इंटरमीडिएट सॉर्ट परिणामों को सीमित कर सकते हैं, आकार को कम कर सकते हैं किसी भी अस्थायी डेटा के। –

+0

हालांकि, चूंकि एक संघ * किसी भी * टेबल, गणना, अक्षर, आदि का संयोजन हो सकता है, एक संघ * एक मध्यवर्ती परिणाम बनाना और क्रमबद्ध करना चाहिए। शायद आप अनुकूलित कर सकते हैं, लेकिन सामान्य संस्करण * काम * चाहिए। –

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

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