Tıpkı @Alvaro'nun Django'nun GROUP BYifade için doğrudan karşılığını yanıtlaması gibi :
SELECT actor, COUNT(*) AS total
FROM Transaction
GROUP BY actor
aşağıdaki yöntemlerin kullanımı values()ve annotate()yöntemidir:
Transaction.objects.values('actor').annotate(total=Count('actor')).order_by()
Ancak bir şeye daha dikkat çekilmelidir:
Model tanımlanan varsayılan bir sipariş varsa class Meta, .order_by()fıkra uygun sonuçlar için zorunludur. Hiçbir sipariş amaçlanmadığında bile atlayamazsınız.
Ayrıca, yüksek kaliteli bir kod için , hiç olmasa bile her zaman .order_by()sonra bir cümle koymanız önerilir . Bu tür bir yaklaşım, ifadeyi geleceğe hazır hale getirecektir: gelecekteki değişikliklerden bağımsız olarak, amaçlandığı gibi çalışacaktır .annotate()class Meta: orderingclass Meta: ordering
Size bir örnek vereyim. Modelin olsaydı:
class Transaction(models.Model):
actor = models.ForeignKey(User, related_name="actor")
acted = models.ForeignKey(User, related_name="acted", null=True, blank=True)
action_id = models.IntegerField()
class Meta:
ordering = ['id']
O halde böyle bir yaklaşım işe yaramaz:
Transaction.objects.values('actor').annotate(total=Count('actor'))
Django ilave gerçekleştirir Çünkü GROUP BYher alanda üzerindeclass Meta: ordering
Sorguyu yazdırırsanız:
>>> print Transaction.objects.values(
SELECT "Transaction"."actor_id", COUNT("Transaction"."actor_id") AS "total"
FROM "Transaction"
GROUP BY "Transaction"."actor_id", "Transaction"."id"
Toplamanın amaçlandığı gibi çalışmayacağı ve bu nedenle .order_by()maddenin bu davranışı temizlemek ve uygun toplama sonuçları elde etmek için kullanılması gerektiği açık olacaktır.
Bkz .: Resmi Django belgelerinde varsayılan sıralama veya order_by () ile etkileşim .