Django'da Sorgu Yorumlama (annotate) İşleminde Farklı Elemanları Saydırmak.
Python İstanbul mail grubuna ilginç bir soru geldi, buraya not edeyim dedim.
Arkadaşın bir Category, Author ve Post adında üç adet modeli var:
class Category(models.Model):
slug = ...
name = ...
class Post(models.Model)
title = ...
category = ForeignKey(Category)
author = ...
class Author(models.Model):
name = ...
Sorgulamak istenilen şey ise, kategori listesini her bir kategoride yazısı olan yazar sayılarıyla birlikte listelemek. Yani şöyle bir liste:
category_id | category | name | author_count |
---|---|---|---|
2 | Django | 4 | 1 |
1 | Python | 3 | 3 |
Burada arkadaş bu sonuçları elde edebilmek için aşağıdaki gibi kümeleme kullanmış (şurda bahsetmiştim)
Category.objects.annotate(\
author_count=Count('post__author')).order_by('-author_count')</pre>
Burda beklenilen şey kategorilerin post_author'ların sayımı birlikte gelmesi. Ancak yanlış giden bir şey var ki iki author var ise bunlar 2'şer Post yaptı ise toplam 4 yazar varmış gibi gözüküyor.
Burada çözüm, yapılan sorguyu tekrarlardan uzak tutarak yapmak. Yani yazarları say ama unique (bunun Türkçe'si nedir?) say dememiz gerekiyor. Bunun için distinct adında bir parametre varmış:
Category.objects.annotate(\
author_count=Count('post__author', distinct=True)
).order_by('-author_count')</pre>