2011-05-11 3 views
12

में डेटा और जटिल एनोटेशन को पिटोटिंग करना Django में ORM हमें संबंधित डेटा के आधार पर क्वेरीसेट्स को आसानी से एनोटेट (फ़ील्ड जोड़ने) की सुविधा देता है, इसलिए मुझे संबंधित डेटा के विभिन्न फ़िल्टर किए गए सबसेट के लिए एकाधिक एनोटेशन प्राप्त करने का कोई तरीका नहीं मिल रहा है।Django ORM

यह django-helpdesk, ओपन-सोर्स डीजेगो-संचालित परेशानी-टिकट ट्रैकर के संबंध में पूछा जा रहा है। मैं डेटा चार्टिंग और रिपोर्टिंग प्रयोजनों के लिए इस तरह पिवट की आवश्यकता है

इन मॉडलों पर विचार करें:

CHOICE_LIST = (
    ('open', 'Open'), 
    ('closed', 'Closed'), 
) 

class Queue(models.model): 
    name = models.CharField(max_length=40) 

class Issue(models.Model): 
    subject = models.CharField(max_length=40) 
    queue = models.ForeignKey(Queue) 
    status = models.CharField(max_length=10, choices=CHOICE_LIST) 

और इस डेटासेट:

कतार:

ID | Name 
---+------------------------------ 
1 | Product Information Requests 
2 | Service Requests 

मुद्दे:

ID | Queue | Status 
---+-------+--------- 
1 | 1  | open 
2 | 1  | open 
3 | 1  | closed 
4 | 2  | open 
5 | 2  | closed 
6 | 2  | closed 
7 | 2  | closed 

मैं इस तरह एक एनोटेशन/कुल नज़र देखने के लिए कुछ करना चाहते हैं:

Queue ID | Name       | open | closed 
---------+-------------------------------+------+-------- 
1  | Product Information Requests | 2 | 1 
2  | Service Requests    | 1 | 3 

यह मूल रूप से, एक crosstab या पिवट तालिका है एक्सेल भाषा में। मैं वर्तमान में कुछ कस्टम एसक्यूएल प्रश्नों का उपयोग करके इस आउटपुट का निर्माण कर रहा हूं, हालांकि अगर मैं Django ORM का उपयोग करने के लिए स्थानांतरित कर सकता हूं, तो मैं अपने एसक्यूएल में WHERE क्लॉज के डोडी सम्मिलन किए बिना डेटा को गतिशील रूप से फ़िल्टर कर सकता हूं।

"बोनस अंक" के लिए: यह कैसे करेगा जहां पिवोट फ़ील्ड (status उपरोक्त उदाहरण में) एक तिथि थी, और हम चाहते थे कि कॉलम महीनों/सप्ताह/तिमाहियों/दिन हों?

उत्तर

6

आपके पास पाइथन है, इसका उपयोग करें।

from collections import defaultdict 
summary = defaultdict(int) 
for issue in Issues.objects.all(): 
    summary[issue.queue, issue.status] += 1 

अब आप अपने summary वस्तु एक दो टपल कुंजी के रूप में कतार, दर्जा प्राप्त है। आप विभिन्न टेम्पलेट तकनीकों का उपयोग करके इसे सीधे प्रदर्शित कर सकते हैं।

या, यदि आप सरल हैं, तो आप इसे एक टेबल जैसी संरचना में पुन: समूहित कर सकते हैं।

table = [] 
queues = list(q for q,_ in summary.keys()) 
for q in sorted(queues): 
    table.append(q.id, q.name, summary.count(q,'open'), summary.count(q.'closed')) 

आपके पास पिवट टेबल करने के लिए बहुत सारे पाइथन तकनीकें हैं।

यदि आप मापते हैं, तो आप पाएंगे कि इस तरह का ज्यादातर पाइथन समाधान वास्तव में शुद्ध SQL समाधान से तेज़ है। क्यूं कर? मैकिंग एसक्यूएल एल्गोरिदम से तेज हो सकती है जिसके लिए ग्रुप-बीई के हिस्से के रूप में एक प्रकार की आवश्यकता होती है।

+1

यदि समस्या तालिका बड़ी है और इसे सामान्य रूप से सामान्य रूप से माना जा सकता है तो यह समाधान खराब हो जाएगा। – JohnnyM

+0

कुछ साल बाद इसे पढ़ने के लिए: मुझे 'collections.defaultdict 'ऑब्जेक्ट में कोई विशेषता नहीं है' count'' 'python3 के साथ' summary.count (q.closed') पर एक टाइपो भी है। –

2

डीजेगो ने ओआरएम को बहुत सारी कार्यक्षमताएं जोड़ दी हैं क्योंकि इस सवाल को मूल रूप से पूछा गया था। Django 1.8 के बाद डेटा को पिवोट करने का उत्तर केस/जब conditional expressions का उपयोग करना है। और एक तीसरा पक्ष ऐप है जो आपके लिए ऐसा करेगा, PyPI और documentation