2010-08-08 19 views
36

Tôi đã có mô hình này:Nhận giá trị khác biệt của QuerySet bởi lĩnh vực

class Visit(models.Model): 
    timestamp = models.DateTimeField(editable=False) 
    ip_address = models.IPAddressField(editable=False) 

Nếu người dùng truy cập nhiều lần trong một ngày, làm thế nào tôi có thể lọc cho hàng độc đáo dựa trên các lĩnh vực ip? (Tôi muốn thăm độc đáo cho ngày hôm nay)

today = datetime.datetime.today() 
yesterday = datetime.datetime.today() - datetime.timedelta(days=1) 

visits = Visit.objects.filter(timestamp__range=(yesterday, today)) #.something? 

EDIT:

tôi thấy rằng tôi có thể sử dụng:

Visit.objects.filter(timestamp__range=(yesterday, today)).values('ip_address') 

để có được một ValuesQuerySet chỉ các lĩnh vực ip. Bây giờ QuerySet của tôi trông như thế này:

[{'ip_address': u'127.0.0.1'}, {'ip_address': u'127.0.0.1'}, {'ip_address': 
u'127.0.0.1'}, {'ip_address': u'127.0.0.1'}, {'ip_address': u'127.0.0.1'}] 

Làm thế nào để lọc này cho tính độc đáo mà không cần đánh giá QuerySet và lấy db hit?

# Hope it's something like this... 
values.distinct().count() 
+0

trùng lặp có thể xảy ra [Chọn giá trị khác biệt từ một lĩnh vực bảng] (http://stackoverflow.com/questions/2466496/select-distinct-values-from-a-table-field) –

Trả lời

32

gì bạn muốn là:

Visit.objects.filter(stuff).values("ip_address").annotate(n=models.Count("pk")) 

Điều này không là nhận được tất cả ip_addresses và sau đó nó được đếm khóa chính (hay còn gọi là số hàng) cho mỗi địa chỉ ip.

+2

Tôi không nghĩ rằng tôi hoàn toàn hiểu chú thích. Như bạn đã viết nó, ValuesQuerySet của tôi bây giờ có "n": 1 được nối thêm vào mỗi mục nhập. Tôi không chắc điều đó nói gì với tôi? – Scott

+7

Vấn đề có lẽ là Meta.ordering - hãy thử điều này 'Visit.objects.filter (stuff) .order_by(). Values ​​(" ip_address "). Annotate (n = models.Count (" pk "))' – Greg

+1

@Greg Cảm ơn bạn! Tôi mới rằng 'order' và' order_by() 'gây ra các vấn đề với' khác biệt' nhưng tôi không biết cách giải quyết nó - mặc dù nó nằm trong tài liệu API QuerySet dưới ['order_by()'] (https://docs.djangoproject.com/en/dev/ref/models/querysets/# order-by) "_Nếu bạn không muốn bất kỳ thứ tự nào được áp dụng cho truy vấn, ngay cả thứ tự mặc định, hãy gọi' order_by() 'không có tham số._ " –

13

Với Alex Trả lời Tôi cũng có n: 1 cho mỗi mục. Ngay cả với một mệnh đề khác biệt().

Đó là lạ vì đây là trả lại số tốt các hạng mục:

Visit.objects.filter(stuff).values("ip_address").distinct().count() 

Nhưng khi tôi lặp qua "(công cụ) .values ​​Visit.objects.filter (" ip_address "). Riêng biệt()" Tôi có nhiều hơn nữa các mặt hàng và một số bản sao ...

EDIT:

mệnh lọc đã gây cho tôi rắc rối. Tôi đã lọc với một lĩnh vực bảng và một JOIN SQL đã được thực hiện đã được phá vỡ những thứ khác biệt. tôi đã sử dụng gợi ý này để xem các truy vấn đã được thực sự sử dụng:

q=Visit.objects.filter(myothertable__field=x).values("ip_address").distinct().count() 
print q.query 

sau đó tôi hoàn nguyên các lớp trên phù thủy tôi đã làm cho các truy vấn và bộ lọc để có một tham gia mà không dựa trên bất kỳ "Visit" ID.

hy vọng điều này giúp

+0

Đây có phải là câu hỏi hay câu trả lời không? – User

+0

nó là một loại bổ sung cho câu trả lời của Alex. Tôi đã thử nó, đã có cùng một vấn đề hơn vfxcode, và sau đó tôi tìm thấy lý do tại sao. Vì vậy, tôi nghĩ rằng tôi nên chia sẻ những phát hiện của tôi. 3 năm sau, tôi thừa nhận câu trả lời của tôi hơi lộn xộn và tôi hiểu tại sao bạn lại hỏi điều này;) –