Сортировка Django внутри групп связанных с объектами внешних ключей - PullRequest
0 голосов
/ 21 декабря 2018

У меня есть следующая модель:

class Mountain(models.Model):
    name = CharField(max_length=200)

class Climbing(models.Model):
    mountain = models.ForeignKey(Mountain)
    climber = CharField(max_length=200)
    date = models.DateField(auto_now_add=True)

Я хочу группировать подъемы по горам и сортировать горы по последним подъемам, а также сортировать подъемы внутри каждой горы.

Everest:
    2018-12-21
    2018-10-10
    2000-01-30

K2:
    2018-12-20
    2018-11-30

theто же самое в коде:

(
    [
        'everest',
        ['2018-12-21', '2018-10-10', '2000-01-30']
    ],
    [
        'K2',
        ['2018-12-20', '2018-11-30']
    ]
)

Какой самый эффективный способ реализовать его в Django, но на стороне базы данных?Я понимаю, что могу делать наборы восхождений, фильтровать по связанным горам и т. Д., Но я хотел бы выполнить все вычисления на сервере postgres.

1 Ответ

0 голосов
/ 21 декабря 2018

Я не понимаю, почему вы хотите проводить вычисления на Postgres, где Django предлагает эффективное решение с помощью ORM?

Кстати, вы можете получить данные, используя order_by через Django ORM:

Climbing.objects.all().order_by('-date', 'mountain__name')

FYI, это ленивый запрос и даже не попадет в базу данных (поэтому эффективность не должна быть проблемой), и вы получите данные, когда вы оцените набор запросов .

Обновление

Попробуйте вот так:

Обновитемодели, подобные следующим:

    class Mountain(models.Model):
        name = CharField(max_length=200)


    class Climbing(models.Model):
        mountain = models.ForeignKey(Mountain, related_name="climbings")  # <-- Here
        climber = CharField(max_length=200)
        date = models.DateField(auto_now_add=True)

        class Meta:
           ordering = ('-date',)  # <-- Here

Затем используйте prefetch_related для извлечения связанных объектов. ( документы )

from django.db.models import Prefetch

prefetch = Prefetch('climbings', Climbing.objects.all())

# OR
# prefetch = Prefetch('climbings', Climbing.objects.only('date'))

mountains = Mountain.objects.all().prefetch_related(prefetch).order_by('name')

for m in mountain:
    print(m.name)
    print(m.climbings.all().values_list('date', flat=True))

# Or
mountains.values('name', 'climbings__date')  # or user values_list if you want it as a list

Обновление 2

Для сортировки по последней дате лазания, попробуйте так:

mountains = Mountain.objects.all().prefetch_related(prefetch).annotate(max_date=Max('climbings__date').order_by('max_date')
...