Einfache Unterabfrage mit OuterRef

8

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%     
mjuk 03.05.2017, 21:13
quelle

1 Antwort

18

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:

%Vor%

Das wird aus zwei Gründen nicht funktionieren:

  1. 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).

  2. 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

in die values verschoben wird %Vor%

Schließlich wird dies produzieren:

%Vor%     
Todor 03.05.2017, 23:47
quelle