Ich frage ein Modell ab:
Members.objects.all()
Und es kehrt zurück:
Eric, Salesman, X-Shop
Freddie, Manager, X2-Shop
Teddy, Salesman, X2-Shop
Sean, Manager, X2-Shop
Ich möchte wissen group_by
, wie Django eine Abfrage in meiner Datenbank am besten auslösen kann, z. B.:
Members.objects.all().group_by('designation')
Was natürlich nicht funktioniert. Ich weiß, dass wir ein paar Tricks machen können django/db/models/query.py
, aber ich bin nur neugierig, wie es geht, ohne zu patchen.
python
django
django-models
einfach hart
quelle
quelle
Members.objects.filter(date=some_date).values('designation').annotate(dcount=Count('designation'))
Members.objects.order_by('disignation').values('designation').annotate(dcount=Count('designation'))
Eine einfache Lösung, aber nicht die richtige, ist die Verwendung von Raw SQL :
Eine andere Lösung besteht darin, die
group_by
Eigenschaft zu verwenden:Sie können jetzt die Ergebnisvariable durchlaufen, um Ihre Ergebnisse abzurufen. Beachten Sie, dass dies
group_by
nicht dokumentiert ist und in zukünftigen Versionen von Django geändert werden kann.Und ... warum willst du verwenden
group_by
? Wenn Sie keine Aggregation verwenden, können Sieorder_by
ein gleiches Ergebnis erzielen.quelle
Sie können das
regroup
Vorlagen-Tag auch zum Gruppieren nach Attributen verwenden. Aus den Dokumenten:Sieht aus wie das:
Es funktioniert auch weiter
QuerySet
s, glaube ich.Quelle: https://docs.djangoproject.com/de/2.1/ref/templates/builtins/#regroup
Bearbeiten: Beachten Sie, dass das
regroup
Tag nicht wie erwartet funktioniert, wenn Ihre Wörterbuchliste nicht nach Schlüsseln sortiert ist. Es funktioniert iterativ. Sortieren Sie Ihre Liste (oder Ihren Abfragesatz) nach dem Schlüssel des Zackenbarschs, bevor Sie sie an dasregroup
Tag übergeben.quelle
Sie müssen benutzerdefiniertes SQL ausführen, wie in diesem Snippet veranschaulicht:
Benutzerdefiniertes SQL über Unterabfrage
Oder in einem benutzerdefinierten Manager, wie in den Online-Django-Dokumenten gezeigt:
Hinzufügen zusätzlicher Manager-Methoden
quelle
Django unterstützt keine kostenlose Gruppierung nach Abfragen . Ich habe es sehr schlecht gelernt. ORM ist nicht dafür ausgelegt, Dinge wie das zu unterstützen, was Sie tun möchten, ohne benutzerdefiniertes SQL zu verwenden. Sie sind beschränkt auf:
cr.execute
Sätze (und eine handgemachte Analyse des Ergebnisses)..annotate()
(Die Gruppierung nach Sätzen wird im untergeordneten Modell für .annotate () ausgeführt, in Beispielen wie dem Aggregieren von lines_count = Count ('lines'))).Über ein Queryset können
qs
Sie aufrufen,qs.query.group_by = ['field1', 'field2', ...]
aber es ist riskant, wenn Sie nicht wissen, welche Abfrage Sie bearbeiten, und keine Garantie dafür haben, dass sie funktioniert und keine Interna des QuerySet-Objekts beschädigt. Außerdem handelt es sich um eine interne (undokumentierte) API, auf die Sie nicht direkt zugreifen sollten, ohne zu riskieren, dass der Code nicht mehr mit zukünftigen Django-Versionen kompatibel ist.quelle
Es gibt ein Modul, mit dem Sie Django-Modelle gruppieren und dennoch mit einem QuerySet im Ergebnis arbeiten können: https://github.com/kako-nawao/django-group-by
Zum Beispiel:
'book / books.html'
Der Unterschied zu den
annotate
/aggregate
basic Django-Abfragen besteht in der Verwendung der Attribute eines verwandten Feldes, zbook.author.last_name
.Wenn Sie die PKs der Instanzen benötigen, die zusammen gruppiert wurden, fügen Sie die folgende Anmerkung hinzu:
HINWEIS:
ArrayAgg
ist eine Postgres-spezifische Funktion, die ab Django 1.9 verfügbar ist: https://docs.djangoproject.com/de/1.10/ref/contrib/postgres/aggregates/#arrayaggquelle
values
Methode. Es ist für einen anderen Zweck, denke ich.values
ist ein SQL,select
währendgroup_by
es ein SQL istgroup by
(wie der Name schon sagt ...). Warum das Downvote? Wir verwenden solchen Code in der Produktion, um komplexegroup_by
Anweisungen zu implementieren .group_by
"verhält sich hauptsächlich wie die Wertemethode, aber mit einem Unterschied ..." Das Dokument erwähnt SQL nichtGROUP BY
und der Anwendungsfall, den es bereitstellt, deutet nicht darauf hin, dass es etwas mit SQL zu tun hatGROUP BY
. Ich werde die Abwahl zurückziehen, wenn jemand dies klargestellt hat, aber dieses Dokument ist wirklich irreführend.values
gelesen hatte , stellte ich fest, dass ich selbst vermisst habe, dass esvalues
wie ein GROUP BY funktioniert. Es ist meine Schuld. Ich denke, es ist einfacher zu verwendenitertools.groupby
als diese Django-Gruppierung, wenn sievalues
nicht ausreicht.group by
von oben mit einem einfachenvalues
Aufruf zu tun - mit oder ohneannotate
und ohne alles aus der Datenbank abzurufen. Ihr Vorschlagitertools.groupby
funktioniert für kleine Datensätze, jedoch nicht für mehrere Tausend Datensätze, die Sie wahrscheinlich paginieren möchten. An diesem Punkt müssen Sie natürlich über einen speziellen Suchindex nachdenken, der ohnehin vorbereitete (bereits gruppierte) Daten enthält.Das Dokument besagt, dass Sie Werte verwenden können, um das Abfrageset zu gruppieren.
Mit diesem Code können Sie alle Bücher finden und nach Namen gruppieren:
Sie können einige cheet Blatt sehen hier .
quelle
Wenn ich mich nicht irre, können Sie verwenden, was auch immer-Abfragesatz .group_by = [' Feld ']
quelle
Zuerst müssen Sie Sum importieren, dann ..
quelle