Django에서 SELECT MAX를 수행하는 방법은 무엇입니까?


91

필드의 최대 값을 제공하기 위해 쿼리를 실행하는 방법에 대한 개체 목록이 있습니다.

이 코드를 사용하고 있습니다.

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

등급은 정수입니다.

답변:


172

참조 . 코드는 다음과 같습니다.

from django.db.models import Max
# Generates a "SELECT MAX..." query
Argument.objects.aggregate(Max('rating')) # {'rating__max': 5}

기존 쿼리 세트에서도 사용할 수 있습니다.

from django.db.models import Max
args = Argument.objects.filter(name='foo') # or whatever arbitrary queryset
args.aggregate(Max('rating')) # {'rating__max': 5}

이 최대 값을 포함하는 모델 인스턴스가 필요한 경우 게시 한 코드가이를 수행하는 가장 좋은 방법 일 것입니다.

arg = args.order_by('-rating')[0]

쿼리 세트가 비어있는 경우, 즉 쿼리와 일치하는 인수가없는 경우 오류가 발생합니다 ( [0]부분이를 발생 시키기 때문에 IndexError). 그 행동을 피하고 대신 단순히 None그 경우에 반환 하려면 .first()다음을 사용하십시오 .

arg = args.order_by('-rating').first() # may return None

4
Max가있는 actuall 인수 개체가 필요하므로 세부 정보 필드를 인쇄 할 수 있습니다. args.aggregate (Max ( 'rating')) 호출은 가장 높은 등급 만 반환합니다. 가장 높은 등급을 가진 arg를 찾고 있습니다.
Johnd

1
종료 코드-Argument.objects.order_by ( "-rating") [0]에 어떤 문제가 있습니까?
AdamKG

73

Django에는 또한 최신 (최대 값) 항목을 찾는 ' latest (field_name = None) '함수가 있습니다. 날짜 필드뿐만 아니라 문자열 및 정수에서도 작동합니다.

해당 함수를 호출 할 때 필드 이름을 제공 할 수 있습니다.

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

또는 모델 메타 데이터에서 해당 필드 이름을 이미 제공 할 수 있습니다.

from django.db import models

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

이제 매개 변수없이 'latest ()'를 호출 할 수 있습니다.

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

3
이것은를 사용하는 좋은 방법입니다 latest(). 최소값을 가진 레코드가 필요한 경우 earliest().
SaeX

7
latest()그리고 earliest()너무 비 날짜 필드와 함께 작동하지만, 구현의 부작용이다. 당신은 사용해야 <your-queryset>.order_by('<interested-field>').first()이나 <your-queryset>.order_by('<interested-field>').last()여전히 장고 개발자가 변경됩니다 작품 않더라도 코드 확인 latest()earliest()날짜 필드 만에 작업을 구현합니다.
mrnfrancesco

이것은 잘못된 대답입니다. 1) 이전에 구현 된 세부 사항이며 향후 변경 될 수 있습니다. 2) 읽기가 매우 어렵습니다. 최대 개수는 반드시 최근 저장된 개수가 아닙니다 (또는 다른 의미에서)
Mikhail Gerasimov

47

내 프로젝트에 대해 이것을 테스트했으며 O (n) 시간에서 최대 / 최소를 찾습니다.

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.aggregate(Max('rating'))['rating__max']
return App.objects.get(rating=max_rating)

이것은 전체 테이블을 정렬하고 최상위 (약 O (n * logn))를 얻는 것보다 효율적으로 최대 요소 중 하나를 얻을 수 있도록 보장합니다.


8
Big-O는 때때로 실제로, 특히 계수와 구현이 중요한 더 작은 n에 대해 입증되지 않습니다. 귀하의 코드는 python / django에 있으며, 이는 바이트 코드로 컴파일되며 최적화되거나 최적화되지 않을 수 있습니다. 데이터베이스는 기계 명령어로 최적화되고 컴파일 된 언어로 작성되었을 가능성이 높습니다. 게다가, 함수가 최대 값 만 찾는다면 데이터베이스는 정렬 할 실제 이유가 없습니다. 기본 제공 데이터베이스 함수를 통해 직접 빌드 코드를 사용하는 데 익숙해지기 전에 타이밍 데이터를보고 싶습니다.
benevolentprof

5
@afahim 나는 이것이 당신이 게시하는 코드가 완전히 정확하다고 생각하지 않습니다. 최대 값이 두 개 이상인 경우 (별표 5 개가있는 두 개의 앱이 있다고 가정 해 보겠습니다) "get"을 사용하면 오류가 발생합니다.
Raydel Miranda
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.