Programing

개수 및 그룹화 기준에 해당하는 Django

lottogame 2020. 9. 6. 11:48
반응형

개수 및 그룹화 기준에 해당하는 Django


다음과 같은 모델이 있습니다.

class Category(models.Model):
    name = models.CharField(max_length=60)

class Item(models.Model):
    name = models.CharField(max_length=60)
    category = models.ForeignKey(Category)

각 범주에 대한 항목의 개수 (단지 개수)를 선택하기를 원하므로 SQL에서는 다음과 같이 간단합니다.

select category_id, count(id) from item group by category_id

이 "장고 방식"을 수행하는 것과 동등한 것이 있습니까? 아니면 일반 SQL이 유일한 옵션입니까? Django count () 메서드에 익숙 하지만 group by 가 거기에 어떻게 들어 맞는지 모르겠습니다 .


방금 발견 한 것처럼 Django 1.1 집계 API로이를 수행하는 방법은 다음과 같습니다.

from django.db.models import Count
theanswer = Item.objects.values('category').annotate(Count('category'))

( 업데이트 : 전체 ORM 집계 지원이 이제 Django 1.1에 포함되었습니다 . 개인 API 사용에 대한 아래의 경고에 충실하게 여기에 설명 된 방법은 Django 1.1 버전 이후에서 더 이상 작동하지 않습니다. 이유를 알아 내지 않았습니다. 1.1 이상을 사용하는 경우 어쨌든 실제 집계 API를 사용해야 합니다.)

코어 집계 지원은 이미 1.0에있었습니다. 문서화되지 않고 지원되지 않으며 아직 친숙한 API가 없습니다. 그러나 1.1이 도착할 때까지 어쨌든 사용할 수있는 방법은 다음과 같습니다 (사용자의 책임이며 query.group_by 속성은 공용 API의 일부가 아니며 변경 될 수 있음을 완전히 알고 있음).

query_set = Item.objects.extra(select={'count': 'count(1)'}, 
                               order_by=['-count']).values('count', 'category')
query_set.query.group_by = ['category_id']

그런 다음 query_set을 반복하면 반환되는 각 값은 "category"키와 "count"키가있는 사전이됩니다.

여기에서 -count로 주문할 필요는 없습니다. 이것은 단지 어떻게 수행되는지 보여주기 위해 포함 된 것입니다 (쿼리 셋 생성 체인의 다른 곳이 아니라 .extra () 호출에서 수행되어야합니다). 또한 count (1) 대신 count (id)라고 말할 수 있지만 후자가 더 효율적일 수 있습니다.

또한 .query.group_by를 설정할 때 값은 Django 필드 이름 ( 'category')이 아닌 실제 DB 열 이름 ( 'category_id')이어야합니다. 이는 Django 용어가 아닌 DB 용어로 모든 것이있는 수준에서 쿼리 내부를 조정하기 때문입니다.


Django 1.1에서 그룹화가 작동하는 방식에 대해 약간 혼란 스러웠 기 때문에 여기에서 정확히 사용하는 방법에 대해 자세히 설명하겠다고 생각했습니다. 먼저 Michael의 말을 반복합니다.

방금 발견 한 것처럼 Django 1.1 집계 API로이를 수행하는 방법은 다음과 같습니다.

from django.db.models import Count
theanswer = Item.objects.values('category').annotate(Count('category'))

또한 당신이 필요합니다 from django.db.models import Count!

카테고리 만 선택한 다음라는 주석이 추가 category__count됩니다. 기본 순서에 따라 이것이 필요한 전부일 수 있지만 기본 순서가이 이외의 필드를 사용하는 경우 category작동하지 않습니다 . 그 이유는 주문에 필요한 필드도 선택되고 각 행을 고유하게 만들어서 원하는 방식으로 그룹화 할 수 없기 때문입니다. 이 문제를 해결하는 한 가지 빠른 방법은 순서를 재설정하는 것입니다.

Item.objects.values('category').annotate(Count('category')).order_by()

원하는 결과를 정확히 얻을 수 있습니다. 주석의 이름을 설정하려면 다음을 사용할 수 있습니다.

...annotate(mycount = Count('category'))...

그러면 mycount결과에 주석 이 표시됩니다.

그룹화에 관한 다른 모든 것은 나에게 매우 간단했습니다. 더 자세한 정보 Django Aggregation API 를 확인하세요 .


어때? (느린 것 말고)

counts= [ (c, Item.filter( category=c.id ).count()) for c in Category.objects.all() ]

많은 행을 가져 오더라도 짧다는 장점이 있습니다.


편집하다.

하나의 쿼리 버전입니다. BTW, 이것은 종종 데이터베이스의 SELECT COUNT (*)보다 빠릅니다 . 그것을보십시오.

counts = defaultdict(int)
for i in Item.objects.all():
    counts[i.category] += 1

참고 URL : https://stackoverflow.com/questions/327807/django-equivalent-for-count-and-group-by

반응형