Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Consulta Django no relacionamento Um para Muitos


Isso não é algo que você pode ou deve tentar alcançar com uma anotação do conjunto de consultas. Isso ocorre porque as anotações só podem ser usadas para funções de agregação como Count , Sum etc.

Se entendi sua pergunta corretamente, você pode obter essas informações ao iterar no conjunto de consultas:
for order in Order.objects.all():
    types = order.details.values_list('product_type', flat=True)

Você pode tornar isso mais eficiente pré-buscando o OrderDetail relacionado linhas para cada pedido:
for order in Order.objects.prefetch_related('details'):
    types = order.details.values_list('product_type', flat=True)

Alternativamente, você pode recuperar alguns valores de cada pedido usando este método:
queryset = Order.objects.values('id', 'user_id', 'details__product_type')

Ele deve fazer uma única consulta de banco de dados. No entanto, veja as notas aqui sobre como isso funciona:https:/ /docs.djangoproject.com/en/1.9/ref/models/querysets/#values

Seu conjunto de consultas produzirá dicts em vez de instâncias de modelo. E você não terá uma boa lista de product_type s... em vez disso, você receberá linhas 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'},
    ...
]

... então você terá que agrupar essas linhas em python na estrutura de dados desejada:
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'])