Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Django-Abfrage in einer Eins-zu-Viele-Beziehung

Dies können oder sollten Sie nicht mit einer Queryset-Annotation erreichen. Dies liegt daran, dass Annotationen nur für Aggregationsfunktionen wie Count verwendbar sind , Sum usw.

Wenn ich Ihre Frage richtig verstanden habe, können Sie diese Informationen erhalten, wenn Sie über das Abfrageset iterieren:

for order in Order.objects.all():
    types = order.details.values_list('product_type', flat=True)

Sie können dies effizienter gestalten, indem Sie das zugehörige OrderDetail vorab abrufen Zeilen für jede Bestellung:

for order in Order.objects.prefetch_related('details'):
    types = order.details.values_list('product_type', flat=True)

Alternativ können Sie mit dieser Methode einige Werte aus jeder Bestellung abrufen:

queryset = Order.objects.values('id', 'user_id', 'details__product_type')

Es sollte eine einzelne DB-Abfrage durchführen. Beachten Sie jedoch die Hinweise hier, wie dies funktioniert:https:/ /docs.djangoproject.com/en/1.9/ref/models/querysets/#values

Ihr Abfragesatz gibt Diktate anstelle von Modellinstanzen aus. Und Sie erhalten keine schöne Liste von product_type s... stattdessen erhalten Sie wiederholte Zeilen wie:

[
    {'id': 1, 'user_id': 1, 'product_type': 'chair'},
    {'id': 1, 'user_id': 1, 'product_type': 'table'},
    {'id': 2, 'user_id': 3, 'product_type': 'chair'},
    ...
]

... also müssen Sie diese Zeilen in Python in die gewünschte Datenstruktur gruppieren:

from collections import OrderedDict

grouped = OrderedDict()
for order in Order.objects.values('id', 'user_id', 'details__product_type'):
    if order['id'] not in grouped:
        grouped[order['id']] = {
            'id': order['id'],
            'user_id': order['user_id'],
            'types': set(),
        }
    grouped[order['id']]['types'].add(order['details__product_type'])