Использование ForeignKey для сортировки с order_by и отличным не работает - PullRequest
0 голосов
/ 15 марта 2019

Я пытаюсь отсортировать модель Game по каждому title и самой последней update (записи) без возврата дубликатов.

views.py

'recent_games': Game.objects.all().order_by('title', '-update__date_published').distinct('title')[:5],

Отличный метод в запросе работает отлично, однако update__date_published, похоже, не работает.

models.py

Модель - Игра

class Game(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(unique=True)
    description = models.TextField()
    date_published = models.DateTimeField(default=timezone.now)
    cover = models.ImageField(upload_to='game_covers')
    cover_display = models.ImageField(default='default.png', upload_to='game_displays')
    developer = models.CharField(max_length=100)
    twitter = models.CharField(max_length=50, default='')
    reddit = models.CharField(max_length=50, default='')
    platform = models.ManyToManyField(Platform)

    def __str__(self):
        return self.title

Модель - Обновление

class Update(models.Model):
    author = models.ForeignKey(User, models.SET_NULL, blank=True, null=True,)  # If user is deleted keep all updates by said user
    article_title = models.CharField(max_length=100, help_text="Use format: Release Notes for MM/DD/YYYY")
    content = models.TextField(help_text="Try to stick with a central theme for your game. Bullet points is the preferred method of posting updates.")
    date_published = models.DateTimeField(db_index=True, default=timezone.now, help_text="Use date of update not current time")
    game = models.ForeignKey(Game, on_delete=models.CASCADE)
    article_image = models.ImageField(default='/media/default.png', upload_to='article_pics', help_text="")
    platform = ChainedManyToManyField(
        Platform,
        horizontal=True,
        chained_field="game",
        chained_model_field="game",
        help_text="You must select a game first to autopopulate this field. You can select multiple platforms using Ctrl & Select (PC) or ⌘ & Select (Mac).")

Ответы [ 3 ]

0 голосов
/ 15 марта 2019

См. Это для distinct ссылка Примеры (те, которые после первого будут работать только на PostgreSQL)

См. Этот для Обратного запроса - См. Этот для - update__date_published

Пример -

Entry.objects.order_by('blog__name', 'mod_date').distinct('blog__name', 'mod_date')

Ваш запрос -

Game.objects.order_by('title', '-update__date_published').distinct('title')[:5]
0 голосов
/ 15 марта 2019

Вы сказали:

Кажется, что -update__date_published не работает, поскольку Игры возвращаются только в алфавитном порядке.

Причина в том, что первое поле order_by имеет значение title; поле вторичного ордера -update__date_published сработает только в том случае, если у вас будет несколько идентичных title с, чего нет у вас из-за distinct().

Если вы хотите, чтобы объекты Game упорядочивались при последнем обновлении, а не по их названию, пропуск title в упорядочивании кажется очевидным решением, пока вы не получите ProgrammingError, для DISTINCT ON field которого требуется field в начале. пункта ORDER BY.

Реальное решение для сортировки игр по последнему обновлению:

games = (Game.objects
    .annotate(max_date=Max('update__date_published'))
    .order_by('-update__date_published'))[:5]
0 голосов
/ 15 марта 2019

Самое вероятное недоразумение здесь - это объединение в вашем запросе orm.Обычно они лениво загружаются, поэтому поле date_published пока недоступно, но вы пытаетесь с ним разобраться.Вам нужен метод select_related, чтобы загрузить отношение fk как объединение.

'recent_games': Game.objects.select_related('update').all().order_by('title', '-update__date_published').distinct('title')[:5]

...