Ich versuche eine sehr einfache Unterabfrage zu erstellen, die OuterRef verwendet (nicht für praktische Zwecke, nur um es zum Laufen zu bringen), aber laufe immer wieder in denselben Fehler.
posts / models.py
%Vor%manage.py Shell-Code
%Vor%Die letzten zwei Zeilen sollten mir eine Anzahl von Tags für jedes Post-Objekt geben. Und hier bekomme ich den gleichen Fehler:
%Vor% Eines der Probleme mit Ihrem Beispiel besteht darin, dass Sie queryset.count()
nicht als Unterabfrage verwenden können, weil .count()
versucht, das Abfrage-Set auszuwerten und die Anzahl zurückzugeben.
Man könnte also meinen, dass der richtige Ansatz darin bestünde, stattdessen Count()
zu verwenden. Vielleicht in etwa so:
Das wird aus zwei Gründen nicht funktionieren:
Das Tag
-Abfragenetz wählt alle Tag
-Felder aus, während Count
nur auf ein Feld zählen kann. Also: Tag.objects.filter(post=OuterRef('pk')).only('pk')
wird benötigt (um auf tag.pk
zählen zu können).
Count
selbst ist keine Subquery
-Klasse, Count
ist eine Aggregate
. Daher wird der von Count
generierte Ausdruck nicht als Subquery
erkannt. Das können wir mit Subquery
beheben.
Und die endgültige Version wäre:
%Vor%Allerdings Wenn Sie die Abfrage überprüfen, die erstellt wird
%Vor% Sie bemerken vielleicht, dass wir eine GROUP BY
-Klausel haben. Das liegt daran, dass Count ein Aggregat ist. Im Moment wirkt sich dies nicht auf das Ergebnis aus, in einigen anderen Fällen jedoch. Deshalb schlagen die Dokumente ein wenig vor bit different approach, wobei die Aggregation über eine bestimmte Kombination von subquery
+ values
+ annotate
values
verschoben wird
%Vor%
Schließlich wird dies produzieren:
%Vor%Tags und Links python django mysql django-queryset django-database