提问人:Nikoi Nikoi 提问时间:11/15/2023 最后编辑:Nikoi Nikoi 更新时间:11/15/2023 访问量:28
使用注解的 Django ORM ForeignKey 查询集输出
Django ORM ForeignKey queryset output using annotations
问:
我有以下 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,不是这 2 个full_name和movies_num,但我想保留相同的组和顺序逻辑。 如何做到这一点?
答:
2赞
willeM_ Van Onsem
11/15/2023
#1
不要用,它将一个模型对象转换成一个字典,这也是一个原始的痴迷反模式[refactoring.guru]:.values()
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'
)
评论
.values()