Django: трансформировать диктат запроса - PullRequest
0 голосов
/ 19 июня 2019

Я использую следующий код для извлечения моих данных из диктата.

test = self.events_max_total_gross()
events = organizer.events.all()
    for event in events:
        test.get(event.pk, {}).values()
        [...]

Я использую этот набор запросов для получения данных.У меня вопрос: имеет ли смысл преобразование в конце или есть лучший способ получить доступ к диктату (не трансформируя его в первую очередь).Поскольку у меня есть несколько из них, мой подход, похоже, не следует принципу СУХОЙ.

def events_max_total_gross(self):

    events_max_total_gross = (
        Event.objects.filter(
            organizer__in=self.organizers,
            status=EventStatus.LIVE
        )
        .annotate(total_gross=Sum(F('tickets__quantity') * F('tickets__price_gross')))
        .values('pk', 'total_gross')
    )

    """
    Convert this
    [
        {
            'pk': 2,
            'total_gross': 12345
        },
        {
            'pk': 3,
            'total_gross': 54321
        },
        ...
    ]

    to this:
    {
        2: {
            'total_gross': 12345,
        },
        3: {
            'total_gross': 12345,
        }
        ...
    }
    """

    events_max_total_gross_transformed = {}

    for item in events_max_total_gross:
        events_max_total_gross_transformed.setdefault(
            item['pk'], {}
        ).update({'total_gross': item['total_gross']})

    return events_max_total_gross_transformed

Ответы [ 2 ]

1 голос
/ 19 июня 2019

Использование:

transformed = { 
    v['pk']: { 'total_gross': v['total_gross'] } for v in events_max_total_gross 
}

Это называется понимание Python dict. Google этот термин, если вы хотите учебники или примеры.

0 голосов
/ 19 июня 2019

Если я правильно понял, то для каждого события организатора вам нужно total_gross, вы можете запросить вот так, вместо того, чтобы проходить события и events_max_total_gross в цикле.

  1. Сначала получите все события этого конкретного организатора.

    event_ids = Event.objects.filter(organizer=organizer).values_list('id',flat=True)

  2. Запустите это тогда:

    Event.objects.filter( id__in=event_ids, organizer__in=self.organizers, status=EventStatus.LIVE ) .annotate(total_gross=Sum(F('tickets__quantity') * F('tickets__price_gross'))) .values('pk', 'total_gross') )

Таким образом, вы сохраните свое преобразование dict и зациклите его снова.

В случае, если вам нужно сделать это из-за какого-то другого требования, вы можете использовать Python DICT-понимание:

events_max_total_gross_transformed = { event['pk']: { 'total_gross': event['total_gross'] } for event in events_max_total_gross }

Но так как у вас есть несколько из них, вы можете взглянуть на proxy-models , которые также могут помочь. Здесь вы можете написать функции менеджера, которые помогут вам с вашими запросами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...