使用注释的Django ORMforeignKey查询集输出

问题描述 投票:0回答:1

我有以下 3 个 django 模型(使用一些抽象):

class Person(models.Model):
    full_name = models.CharField(max_length=120, validators=[MinLengthValidator(2)])
    birth_date = models.DateField(default='1900-01-01')
    nationality = models.CharField(max_length=50, default='Unknown')

    class Meta:
        abstract = True


class Director(Person):
    years_of_experience = models.SmallIntegerField(validators=[MinValueValidator(0)], default=0)

    objects = DirectorManager()


class Actor(Person):
    is_awarded = models.BooleanField(default=False)
    last_updated = models.DateTimeField(auto_now=True)


class Movie(models.Model):
    MOVIE_GENRES = (
        ('Action', 'Action'),
        ('Comedy', 'Comedy'),
        ('Drama', 'Drama'),
        ('Other', 'Other')
    )

    title = models.CharField(max_length=150, validators=[MinLengthValidator(5)])
    genre = models.CharField(max_length=6, choices=MOVIE_GENRES, default='Other')
    rating = models.DecimalField(max_digits=3, decimal_places=1, validators=[MinValueValidator(0.0), MaxValueValidator(10.0)], default=0)
    director = models.ForeignKey(Director, on_delete=models.CASCADE)
    starring_actor = models.ForeignKey(Actor, on_delete=models.SET_NULL, blank=True, null=True)
    actors = models.ManyToManyField(Actor, related_name="actors")

正如您在上面的代码中看到的,我还有 1 个经理。这是:

class DirectorManager(models.Manager):
    def get_directors_by_movies_count(self):
        return self.all().values("full_name").annotate(movies_num=Count("movie__director")).order_by("-movies_num", "full_name")

这是我的问题。我需要这样的输出:

<QuerySet [<Director: Francis Ford Coppola>, <Director: Akira Kurosawa>...>

相反,我收到了这个:

<QuerySet [{'full_name': 'Francis Ford Coppola', 'movies_num': 2}, {'full_name': 'Akira Kurosawa', 'movies_num': 1}...]>

所以,我只需要一条记录:Director,而不是这两个 full_name 和 movie_num,但我想保留相同的组和顺序逻辑。 如何做到这一点?

django django-models orm annotations django-queryset
1个回答
0
投票

不要使用

.values()
,它将模型对象转换为字典,这也是一种原始痴迷反模式[refactoring.guru]

from django.db.models import Count


class DirectorManager(models.Manager):
    def get_directors_by_movies_count(self):
        return self.annotate(movies_num=Count('movie')).order_by(
            '-movies_num', 'full_name'
        )
© www.soinside.com 2019 - 2024. All rights reserved.