2010-06-28 29 views
5

Tôi đã tìm kiếm khắp nơi để có câu trả lời cho điều này nhưng không thể tìm thấy bất cứ điều gì. Có lẽ đây chỉ là một câu hỏi ngu ngốc hoặc một câu hỏi thực sự phức tạp. Ở đây là:Chú thích một queryset với sự khác biệt ngày trung bình? (django)

Hãy nói rằng mô hình của tôi là thế này (giả django code):

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

EventType 
    name = CharField 

Những gì tôi muốn biết là thời gian thời gian trung bình cho mỗi loại sự kiện. Những gì tôi làm bây giờ là tính toán thời lượng trung bình bất cứ khi nào một sự kiện mới được tạo ra (phương thức lưu) và có được lưu trữ trong cột average_duration trong EventType. Vấn đề với phương pháp này là tôi không thể trả lời các câu hỏi như "thời gian thời gian trung bình cho các sự kiện loại X, trong năm Y" là gì. Vì vậy, thay vì thêm nhiều cột để trả lời các câu hỏi như thế này, tôi muốn thực hiện nó trong "thời gian thực".

Điều này có thể được thực hiện bằng cách chú thích bộ truy vấn không? Đầu tiên, tôi sẽ phải có sự khác biệt về ngày cho từng loại sự kiện, sau đó đến mức trung bình của chúng, và sau đó chú thích bộ truy vấn sự kiện với mức trung bình đó, tôi giả định.

Trả lời

1

Tôi nghĩ đặt cược tốt nhất của bạn là tạo chế độ xem SQL với cột date_end - date_start, tạo mô hình django trên chế độ xem này và sau đó bạn có thể truy vấn chế độ xem và chú thích nó theo ý muốn. Tôi đã làm điều này với các mô hình similars cho bạn và có lẽ tôi có thể trích xuất một số mã thú vị cho bạn nếu bạn cần.

+0

Yes nếu bạn có thể cung cấp một số ví dụ mã nó sẽ là tuyệt vời, nhờ –

1

Bạn sẽ cần phải tạo ra một queryset với phương pháp extra để thêm phần chênh lệch ngày để mỗi hàng

Sau đó, sử dụng phương pháp aggregate để tính trung bình cho cột vừa mới thêm của bạn:

Nhưng hãy thận trọng , phương pháp này chậm và sẽ không mở rộng. Lưu trữ giá trị được tính trên event_type là tùy chọn tốt nhất của bạn.

2

tôi sẽ đề nghị bạn nên lưu trữ trong suốt thời gian sự kiện như một cột:

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) 

Sau đó, bạn có thể sử dụng thư viện này: http://code.google.com/p/django-cube/ để tính toán tỷ lệ trung bình trên kích thước khác nhau (năm, loại, hoặc khác):

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

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

Sử dụng các khối như thế này:

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

Hoặc bạn có thể được tất cả các trung bình trên tất cả các năm:

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

Hoặc theo loại năm/sự kiện:

>>> 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

Tôi không biết nhưng giải pháp này có vẻ như phá vỡ ORM để tính toán một giá trị, tuy nhiên, tôi nghĩ rằng Django không hỗ trợ này được nêu ra. –

18

Chỉ cần một bản cập nhật. Trong django 1.8 nó có thể làm:

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) 

sau đó bạn có thể chạy các truy vấn như:

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

Không phải là date_end - date_start? –

+0

@AndreBossard bạn hoàn toàn đúng. cảm ơn – ryuusenshi

+1

Thử nghiệm trong Django 1.8, điều này dường như không hoạt động khi áp dụng cho các hàm tổng hợp (ví dụ: Event.objects.annotate (duration = duration) .aggregrate (Avg ('duration'))) –

Các vấn đề liên quan