Django - 按外键排序

3

我有一个名为“电影(Movie)”的类:

class Movie(models.Model):
    title = models.CharField(max_length=511)
    tmdb_id = models.IntegerField(null=True, blank=True, unique=True)
    release = models.DateField(null=True, blank=True)
    poster = models.TextField(max_length=500, null=True)
    backdrop = models.TextField(max_length=500, null=True, blank=True)
    popularity = models.TextField(null=True, blank=True)

还有一个名为Trailer的类:

class Trailer(models.Model):
    movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
    link = models.CharField(max_length=100)
    date = models.DateTimeField(auto_now_add=True)

如何按预告片日期显示所有电影?

我尝试过:Movie.objects.order_by('trailer__date'),但会导致多个重复项,并且也没有按正确顺序显示它们,我该如何避免重复项并按Trailer对象的日期对每部电影进行排序,以便每部电影只有一个条目?

编辑:我刚刚注意到它不显示所有条目,而只显示其中一些。

2个回答

4
更新:发帖者想要按最新的预告片日期排序,而不是按最早的预告片日期排序。
你可以在这里使用annotate(注释):
from django.db.models import Max
qs = Movie.objects.values('title').annotate(latest_trailer=Max('trailer__date')).order_by('-latest_trailer')
# Add other columns you want into the `values` if you need them

或者您可以使用原始查询并将其与字典配对使用。
from collections import OrderedDict
qs = Movie.objects.order_by('-trailer__date')
movies = OrderedDict()
for x in qs:
    if x.id not in movies:
        movies[x.id] = x
movies = movies.values()

当电影有多个预告片时,你希望它们按照什么顺序排列并不清楚,因此我猜测是基于最早的预告片。


第一个引发了一个错误NoReverseMatch at /movies/,当我尝试使用以下代码:Movie.objects.annotate(earliest_trailer=Min('trailer__date')).order_by('earliest_trailer')时,它显示了没有重复的电影,但顺序不正确,而且顺序是基于最新的预告片。第二个引发了一个错误:'odict_values' object is not subscriptable,我不确定这是什么意思。 - mari
“编辑:Movie.objects.annotate(earliest_trailer=Min('trailer__date')).order_by('earliest_trailer')” 显示了所有对象,但仍然是随机排序的。 - mari
@mari:你提供的代码不足以帮助我们解决脚本问题,而且上面的示例已经更新为按最新预告片排序。下次请确保在原始帖子中指明这一点。 - 2ps

2

@2ps的答案接近但不符合我的要求,无论是升序还是降序,但最终我根据他的答案找到了一个解决方案:

from django.db.models import Max

qs = Movie.objects.annotate(Max("trailer__date")).order_by('-trailer__date__max')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接