Запись модели списка django с несколькими ссылками

У меня есть следующие модели, которые представляют песни и исполнение каждой песни:

from django.db import models


class Play(models.Model):
     play_day = models.PositiveIntegerField()
     source = models.CharField(
         'source',
         choices=(('radio', 'Radio'),('streaming', 'Streaming'), )
     )
     song = models.ForeignKey(Song, verbose_name='song')    


class Song(models.Model):

     name = models.CharField('Name')

Изображение У меня есть следующие записи:

Песни:

|ID | name                |
|---|---------------------|
| 1 | Stairway to Heaven  |
| 2 | Riders on the Storm |

Пьесы:

|ID | play_day | source    | song_id |
|---|----------|-----------|---------|
| 1 | 2081030  | radio     | 1       |
| 1 | 2081030  | streaming | 1       |
| 2 | 2081030  | streaming | 2       |

Я хотел бы перечислить все треки следующим образом:

| Name                | Day        | Sources          |
|---------------------|------------|------------------|
| Stairway to Heaven  | 2018-10-30 | Radio, Streaming |
| Riders on the Storm | 2018-10-30 | Streaming        |

Я использую Django==1.9.2, django_tables2==1.1.6 и django-filter==0.13.0 с PostgreSQL.

Проблема: я использую Song в качестве модели таблицы и фильтра, поэтому набор запросов начинается с select FROM song. Однако, присоединяясь к игровому столу, я получаю две записи в случае «Лестница в небеса» (я знаю, даже одна - это слишком: https://www.youtube.com/watch?v=RD1KqbDdmuE).

Что я пробовал:

  • Я попытался добавить к Песне отдельный, хотя это создает проблему, заключающуюся в том, что я не могу отсортировать другие столбцы, кроме Song.id (предположим, что я выделяю этот столбец)

  • Aggregate: это дает конечное состояние, фактически словарь, который нельзя использовать с django_tables.

  • Я нашел это решение для PostgreSQL Выбор строк, упорядоченных по некоторому столбцу и отдельно на другом, хотя я не знаю, как это сделать с помощью django.

Вопрос: Что было бы правильным, чтобы показывать по одной дорожке в строке, «агрегирующей» информацию из ссылок с помощью ORM Django?


person ezdazuzena    schedule 30.10.2018    source источник
comment
Я думаю, что правильный способ сделать это - использовать функцию array_agg postgresql (postgresql.org/docs/9.5/static/functions-aggregate.html и lorenstewart.me/2017/12/03/postgresqls-array_agg-function). Django, похоже, действительно поддерживает это (по крайней мере, в версии 2.1: docs.djangoproject.com/en/2.1/ref/contrib/postgres/aggregates/), таким образом, похоже, что это правильный путь. К сожалению, сейчас у меня нет времени протестировать его, поэтому я не могу дать исчерпывающий ответ; однако попробуйте что-нибудь вроде: Song.objects.all().annotate(ArrayAgg(...))   -  person Serafeim    schedule 31.10.2018
comment
@serafeim спасибо, это то, что мне нужно. Не знаю, почему я проигнорировал аннотации и просто суммировал их.   -  person ezdazuzena    schedule 08.11.2018
comment
Рад, что помог! Я добавляю это также как правильный ответ на случай, если кто-то наткнется на вопрос и пропустит комментарий!   -  person Serafeim    schedule 08.11.2018


Ответы (1)


Я думаю, что правильный способ сделать это - использовать функцию array_agg postgresql (http://postgresql.org/docs/9.5/static/functions-aggregate.html и http://lorenstewart.me/2017/12/03/postgresqls-array_agg-function).

Django, похоже, действительно поддерживает это (по крайней мере, в версии 2.1: http://docs.djangoproject.com/en/2.1/ref/contrib/postgres/aggregates/), поэтому кажется, что это правильный путь.

К сожалению, сейчас у меня нет времени протестировать его, поэтому я не могу дать исчерпывающий ответ; однако попробуйте что-нибудь вроде: Song.objects.all().annotate(ArrayAgg(...))

person Serafeim    schedule 08.11.2018