sql >> Database >  >> RDS >> Mysql

Django-query in een-op-veel-relatie

Dit is niet iets dat u kunt of moet proberen te bereiken met een annotatie van een queryset. Dit komt omdat annotaties alleen bruikbaar zijn voor aggregatiefuncties zoals Count , Sum enz.

Als ik je vraag goed heb begrepen, kun je deze informatie krijgen als je de queryset herhaalt:

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

U kunt dit efficiënter maken door de gerelateerde OrderDetail . vooraf op te halen rijen voor elke bestelling:

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

Als alternatief kunt u met deze methode enkele waarden van elke bestelling ophalen:

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

Het zou een enkele db-query moeten doen. Zie echter de opmerkingen hier over hoe dit werkt:https:/ /docs.djangoproject.com/en/1.9/ref/models/querysets/#values

Uw queryset zal dicts uitvoeren in plaats van modelinstanties. En je krijgt geen mooie lijst met product_type s... in plaats daarvan krijg je herhaalde rijen zoals:

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

...dus je zult deze rijen in python dan moeten groeperen in de gewenste datastructuur:

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


  1. Hoe niet-overeenkomende resultaten op te halen in mysql

  2. Parallelle/gelijktijdige downloads beperken - Hoe weet ik of de download is geannuleerd?

  3. com.mysql.jdbc.exceptions.MySQLSyntaxErrorException bij gebruik van PreparedStatement

  4. HTML-tags verwijderen in PostgreSQL