Django의 filter() 메서드가 어떻게 작동하는지 매우 기본적이고 근본적인 것이 없다고 생각합니다.관련 모델 필드의 장고 필터()
사용하여 다음과 같은 모델 :
len(Collection.objects.filter(item__flag=True))
:
class Collection(models.Model):
pass
class Item(models.Model):
flag = models.BooleanField()
collection = models.ForeignKey(Collection)
과 질문의 하단에있는 채우기() 함수를 호출하여 제공하는 데이터와
에서, ./manage.py 쉘에서 다음을 실행하십시오필자가 기대하는 바는 flag = True 인 항목이 하나 이상있는 컬렉션의 수인 "2"를 인쇄한다는 것이 었습니다. 이 기대는 https://docs.djangoproject.com/en/1.5/topics/db/queries/#lookups-that-span-relationships의 문서를 기반으로합니다. 예를 들어 "이 예제는 이름이 '비틀즈 블로그'인 블로그로 모든 항목 개체를 검색합니다.
그러나 위의 호출은 실제로 flag = True 인 Item 레코드의 수인 "6"을 인쇄합니다. 실제로 반환되는 객체는 Collection 객체입니다. 그것은 동일한 컬렉션 개체를 여러 번, 해당 항목 레코드에 대해 한 번 flag = True로 반환하는 것 같습니다. 진정한 인쇄
queryset = Collection.objects.filter(item__flag=True)
queryset[0] == queryset[1]
:이은에 의해 확인 될 수있다.
올바른 동작입니까? 그렇다면 그 이유는 무엇입니까? 그것이 예상되는 것이라면, 문서는 엄격하게 해석 될 수 있지만 각 객체가 여러 번 반환 될 수 있다고 말하는 것은 생략됩니다.
여기에 관련된 예가 있습니다. 이는 매우 놀랍거나 (명백히 잘못된) 행동입니다. 이 경우의 저를 잡은 곳이 exclude() 호출은 커스텀 모델 관리자에 의해 추가되는시키고 호출자 후 필터()을 첨가 하였다
from django.db.models import Count
[coll.count for coll in Collection.objects.filter(item__flag=True).annotate(count=Count("item"))]
[coll.count for coll in Collection.objects.exclude(item=None).filter(item__flag=True).annotate(count=Count("item"))]
제 케이스 지문 "[1,2,4]" , 두 번째 줄에는 "[8,16]"이 표시됩니다.
채우기 기능 :
def populate():
Collection.objects.all().delete()
collection = Collection()
collection.save()
item = Item(collection=collection, flag=True)
item.save()
item = Item(collection=collection, flag=True)
item.save()
item = Item(collection=collection, flag=False)
item.save()
item = Item(collection=collection, flag=False)
item.save()
collection = Collection()
collection.save()
item = Item(collection=collection, flag=True)
item.save()
item = Item(collection=collection, flag=True)
item.save()
item = Item(collection=collection, flag=True)
item.save()
item = Item(collection=collection, flag=True)
item.save()
collection = Collection()
collection.save()
item = Item(collection=collection, flag=False)
item.save()
item = Item(collection=collection, flag=False)
item.save()
item = Item(collection=collection, flag=False)
item.save()
item = Item(collection=collection, flag=False)
item.save()