2009-05-10 31 views
48

Tôi có một danh sách các đối tượng làm thế nào tôi có thể chạy một truy vấn để cung cấp cho các giá trị tối đa của một lĩnh vực:Làm thế nào để thực hiện SELECT MAX ở Django?

Tôi đang sử dụng mã này:

def get_best_argument(self): 
    try: 
     arg = self.argument_set.order_by('-rating')[0].details 
    except IndexError: 
     return 'no posts' 
    return arg 

giá là một số nguyên

Trả lời

97

Xem this. Mã của bạn sẽ giống như sau:

from django.db.models import Max 
# Generates a "SELECT MAX..." statement 
Argument.objects.all().aggregate(Max('rating')) 

Nếu bạn đã nhận được danh sách ra khỏi cơ sở dữ liệu, sau đó bạn muốn làm một cái gì đó như thế này:

from django.db.models import Max 
args = Argument.objects.all() 
# Calculates the maximum out of the already-retrieved objects 
args.aggregate(Max('rating')) 

Đây là chưa được kiểm tra vì vậy tôi có thể đã phạm sai lầm ở đâu đó, nhưng có bạn đi.

+0

typo: "Nhập trung bình" -> "nhập tối đa"? – Tom

+0

yea Tôi đã thực hiện thay đổi trong mã của mình – Johnd

+4

Tôi cần đối tượng đối số actuall có giá trị Lớn nhất, vì vậy tôi có thể in trường chi tiết. Cuộc gọi args.aggregate (Max ('rating')) chỉ trả về xếp hạng cao nhất. Tôi đang tìm kiếm arg với xếp hạng cao nhất. – Johnd

37

Tôi đã thử nghiệm này cho dự án của tôi, nó tìm max/phút trong thời gian O (n) thời gian:

from django.db.models import Max 

#Find the maximum value of the rating, and then get the record with that rating. Notice the double underscores in rating__max 
max_rating = App.objects.all().aggregate(Max('rating'))['rating__max'] 
return App.objects.get(rating = max_rating) 

này được đảm bảo để giúp bạn có một trong những yếu tố tối đa hiệu quả, chứ không phải là phân loại toàn bộ bảng và nhận được hàng đầu (xung quanh O (nlogn)).

+4

Big-O đôi khi không chịu trong thực tế, đặc biệt là cho n nhỏ hơn, nơi hệ số và vấn đề thực hiện. Mã của bạn là python/django, được biên dịch sang bytecode và có thể hoặc không được tối ưu hóa. Cơ sở dữ liệu có khả năng được viết bằng một ngôn ngữ được tối ưu hóa và biên dịch thành các lệnh máy. Bên cạnh đó, cơ sở dữ liệu không có lý do thực sự để sắp xếp, nếu hàm chỉ tìm kiếm giá trị tối đa. Tôi muốn xem dữ liệu thời gian trước khi tôi cảm thấy thoải mái khi sử dụng mã xây dựng tay qua chức năng cơ sở dữ liệu được tích hợp sẵn. – benevolentprof

46

Django cũng có chức năng 'latest(field_name = None)' tìm mục nhập (giá trị tối đa) mới nhất. Nó không chỉ hoạt động với các trường ngày tháng mà còn với các chuỗi và số nguyên.

Bạn có thể cung cấp cho các tên trường khi gọi hàm:

max_rated_entry = YourModel.objects.latest('rating') 
return max_rated_entry.details 

Hoặc bạn đã có thể cung cấp cho rằng tên trường trong mô hình của bạn dữ liệu meta:

from django.db import models 

class YourModel(models.Model): 
    #your class definition 
    class Meta: 
     get_latest_by = 'rating' 

Bây giờ bạn có thể gọi là 'mới nhất () 'không có bất kỳ thông số nào:

max_rated_entry = YourModel.objects.latest() 
return max_rated_entry.details 
+3

Đây là một cách tuyệt vời để sử dụng 'mới nhất()'. Nếu bạn cần bản ghi với giá trị tối thiểu, bạn có thể sử dụng 'sớm nhất()'. – SaeX

+1

'latest()' và 'sớm nhất()' hoạt động với trường không phải là ngày tháng, nhưng nó là một tác dụng phụ của việc thực hiện. Bạn nên sử dụng ' .order_by (''). First()' hoặc ' .order_by ('').last() 'để đảm bảo mã của bạn sẽ vẫn hoạt động ngay cả khi các nhà phát triển Django sẽ thay đổi' latest() 'và' sớm nhất() 'thực hiện để chỉ làm việc với các trường ngày tháng. – mrnfrancesco

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