Sanırım Django'nun filter() yönteminin nasıl çalıştığı konusunda çok temel ve temel bir şey eksik.Django filter() ilgili modelin alanında
kullanarak, aşağıdaki modeller:
len(Collection.objects.filter(item__flag=True))
:
class Collection(models.Model):
pass
class Item(models.Model):
flag = models.BooleanField()
collection = models.ForeignKey(Collection)
ve söz altındaki doldurmak() işlev çağırarak sağlanan veriler
, ./manage.py kabuğu aşağıdaki yürütme deneyinBeklentim, bunun "2" yi basmasıydı; bu, en az bir Öğeyi bayrak = True olan Öğelerin sayısıdır. Bu beklenti, "Bu örnek, adı" Beatles Blog "olan bir Blog'la tüm Giriş nesnelerini alır" şeklindeki bir örneğe sahip olan https://docs.djangoproject.com/en/1.5/topics/db/queries/#lookups-that-span-relationships belgesindeki belgelere dayanıyordu. Ancak, yukarıdaki çağrı aslında "6" basıyor; bu, flag = True olan Item kayıtlarının sayısıdır. Geri dönen gerçek nesneler ise Koleksiyon nesneleridir. Aynı Collection nesnesini bayrak = True ile her bir karşılık gelen Öğe kaydı için bir kez daha döndürüyor gibi görünüyor. Bu, True (Doğru) yazdırılan
tarafından onaylanabilir.
Bu doğru davranış mı? Eğer öyleyse mantık nedir? Beklendiği takdirde, belgeler kesinlikle doğru olarak yorumlanabilir, ancak her nesnenin birden çok kez gönderilebileceğini söylemekten kaçınır.
Burada çok şaşırtıcı (veya sadece yanlış yanlış) davranışlar gibi görünen bir örnek var. Bu bir durumda beni yakaladı nerede bir dışlama() çağrısı bir özel model yöneticisi tarafından eklenen ediliyordu ve arayan sonra bir filtre() ekleyerek oldu:
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"))]
ilk vaka baskılar "[2,4]" ama ikinci baskılar "[8,16]" !!!
Doldur fonksiyonu:
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()