2010-06-28 9 views
5

मैंने इस सब के जवाब के लिए सभी जगह खोज की लेकिन कुछ भी नहीं मिला। शायद यह सिर्फ एक बेवकूफ सवाल है या वास्तव में एक मुश्किल है। संदेश यह है:औसत तारीख अंतर के साथ एक क्वेरीसेट एनोटेट करें? (django)

मान लीजिए कि अपने मॉडल इस (छद्म Django कोड) है दो:

Event 
    type = ForeignKey(EventType) 
    name = CharField 
    date_start = DateField 
    date_end = DateField 

EventType 
    name = CharField 

क्या मैं जानना चाहता हूँ प्रत्येक घटना के प्रकार के लिए औसत अवधि का समय है। जब भी कोई नया ईवेंट बनाया जाता है (विधि सहेजें) और अब इवेंट टाइप में औसत_डिशन कॉलम में संग्रहीत किया गया है तो मैं औसत अवधि की गणना करता हूं। इस दृष्टिकोण के साथ समस्या यह है कि मैं वाई के दौरान टाइप एक्स, की घटनाओं के लिए औसत अवधि का समय "जैसे प्रश्नों का उत्तर नहीं दे सकता। तो इस तरह के सवालों के जवाब देने के लिए और कॉलम जोड़ने की बजाय मैं इसे "वास्तविक समय" में करना पसंद करूंगा।

क्या यह क्वेरीसेट को एनोटेट करके किया जा सकता है? सबसे पहले मुझे प्रत्येक इवेंट प्रकार के लिए डेट अंतर प्राप्त करना होगा, फिर अपने औसत के साथ आना होगा, और फिर उस औसत के साथ इवेंट क्वेरीसेट को एनोटेट करना होगा, मुझे लगता है।

उत्तर

1

मुझे लगता है कि आपकी सबसे अच्छी शर्त date_end - date_start कॉलम के साथ एक SQL व्यू बनाना है, इस दृश्य पर एक django मॉडल बनाएं और फिर आप दृश्य को क्वेरी करने और इच्छिततानुसार एनोटेट करने में सक्षम होंगे। मैंने इसे मॉडल सिमिलर्स के साथ किया है और यदि आपको आवश्यकता हो तो मैं आपके लिए कुछ दिलचस्प कोड निकाल सकता हूं।

+0

हाँ अगर आप कुछ कोड उदाहरण यह बहुत अच्छा होगा, धन्यवाद –

1

आप

फिर अपने ही में जोड़े गए स्तंभ के लिए औसत की गणना करने के aggregate विधि का उपयोग करने के लिए प्रत्येक पंक्ति तारीख अंतर को जोड़ने के लिए extra विधि के साथ एक क्वेरीसमूह बनाने की आवश्यकता होगी:

हालांकि सावधान रहें , यह विधि धीमी है और स्केल नहीं होगी। Event_type पर गणना मूल्य को संग्रहीत करना आपके सर्वोत्तम विकल्प है।

2

मेरा सुझाव है कि आप एक स्तंभ के रूप में ईवेंट अवधि की दुकान: फिर

event_duration = models.IntegerField() 
... 

def __init__(self, *args, **kwargs): 
    super(Event, self).__init__(*args, **kwargs) 
    self.update_event_duration() 


def save(self, **kwargs): 
    self.update_event_duration() 
    super(Event, self).save(*args, **kwargs) 

, तो आप इस लाइब्रेरी का उपयोग कर सकते हैं: कई अलग-अलग आयामों (वर्ष, प्रकार, या अन्य) पर औसत की गणना करने के http://code.google.com/p/django-cube/:

>>> def my_avg(queryset): 
... return queryset.aggregate(Avg("event_duration"))["event_duration__avg"] 

>>> c = Cube(["date_start__year", "type"], Event.objects.all(), my_avg) 

इस तरह घन का उपयोग करें:

>>> c.measure(date_start__year=1999, type=event_type2) 
123.456 

या आप कर सकते हैं

>>> c.measure_dict("date_start__year") 
{1984: {'measure': 111.789}, 1985: {'measure': 234.666}, ...} 

या साल/ईवेंट प्रकार के अनुसार:

>>> c.measure_dict("date_start__year", "type") 
{ 
    1984: {eventtype1: {'measure': 111.789}, eventtype2: {'measure': 234.666}, ...}, 
    1985: {eventtype1: {'measure': 122.79}, eventtype2: {'measure': 233.444}, ...}, 
    ... 
} 
+0

प्रदान कर सकता है मैं नहीं जानता:

from django.db.models import F, ExpressionWrapper, fields duration = ExpressionWrapper(F('date_end') - F('date_start'), output_field=fields.DurationField()) events_with_duration = Event.objects.annotate(duration=duration) 

जिसके बाद आप की तरह क्वेरी चला सकते हैं: Django 1.8 में यह करने के लिए संभव है लेकिन यह समाधान एक मूल्य की गणना करने के लिए ओआरएम को तोड़ने जैसा लगता है, फिर भी, मुझे लगता है कि Django अभी तक इसका समर्थन नहीं करता है। –

18

बस एक अद्यतन सभी वर्षों पर सभी का औसत मिलता है।

events_with_duration.filter(duration_gt=timedelta(days=10)) 
+1

यह date_end नहीं होना चाहिए - date_start? –

+0

@AndreBossard आप बिल्कुल सही हैं। धन्यवाद – ryuusenshi

+1

Django 1.8 में परीक्षण, यह कुल कार्यों पर लागू होने पर काम नहीं करता है (उदाहरण के लिए Event.objects.annotate (अवधि = अवधि) .aggregrate (औसत ('अवधि')) –