Tıpkı @Alvaro'nun Django'nun GROUP BY
ifade 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: ordering
class 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 BY
her 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 .