Mysql
 sql >> Base de données >  >> RDS >> Mysql

Requête Django dans une relation un à plusieurs

Ce n'est pas quelque chose que vous pouvez ou devriez essayer d'obtenir avec une annotation d'ensemble de requêtes. En effet, les annotations ne sont utilisables que pour les fonctions d'agrégation telles que Count , Sum etc.

Si j'ai bien compris votre question, vous pouvez obtenir ces informations lors de l'itération sur le jeu de requête :

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

Vous pouvez rendre cela plus efficace en préchargeant le OrderDetail associé lignes pour chaque commande :

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

Alternativement, vous pouvez récupérer certaines valeurs de chaque commande en utilisant cette méthode :

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

Il devrait faire une seule requête db. Cependant, consultez les notes ici sur la façon dont cela fonctionne :https:/ /docs.djangoproject.com/en/1.9/ref/models/querysets/#values

Votre jeu de requêtes affichera des dicts au lieu d'instances de modèle. Et vous n'obtiendrez pas une belle liste de product_type s... à la place, vous obtiendrez des lignes répétées comme :

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

... vous devrez donc regrouper ces lignes en python dans la structure de données souhaitée :

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