sql >> Base de Datos >  >> RDS >> Mysql

Consulta de Django en una relación de uno a muchos

Esto no es algo que pueda o deba intentar lograr con una anotación de conjunto de consultas. Esto se debe a que las anotaciones solo se pueden usar para funciones de agregación como Count , Sum etc.

Si entendí su pregunta correctamente, puede obtener esta información al iterar sobre el conjunto de consultas:

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

Puede hacer esto más eficiente precargando el OrderDetail relacionado filas para cada pedido:

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

Alternativamente, puede recuperar algunos valores de cada orden usando este método:

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

Debería hacer una sola consulta de base de datos. Sin embargo, vea las notas aquí sobre cómo funciona esto:https:/ /docs.djangoproject.com/en/1.9/ref/models/querysets/#values

Su conjunto de consultas generará dictados en lugar de instancias de modelo. Y no obtendrá una buena lista de product_type s... en su lugar obtendrá filas repetidas como:

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

...entonces tendrás que agrupar estas filas en python en la estructura de datos que quieras:

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'])