1

我似乎无法正确使用 annotate 从我的模型中提取我需要的信息。

我有以下 .model 结构:

class ArtistWorkPlaceQuerySet(models.QuerySet):
    def with_related(self):
        return self.select_related('artist','work', 'place')

class ArtistWorkPlaceManager(models.Manager):
    pass

class PersonWorkPlace(models.Model):
    artist = models.ForeignKey(Artist, verbose_name=_('artist'), related_name='work', on_delete=models.CASCADE)
    work = models.ForeignKey(Work, verbose_name=_('work'), related_name='place', on_delete=models.CASCADE)
    place = models.ForeignKey(Place, verbose_name=_('place'), on_delete=models.CASCADE)

    objects = PersonWorkPlaceManager.from_queryset(PersonWorkPlaceQuerySet)()

class Work(models.Model):
    piece_type = models.CharField(max_length=100, null=True, blank=True) //This is like paintings or sculptures

class Artist(models.Model):
    name = models.CharField(max_length=100)

class Place(models.Model):
    name = models.CharField(max_length=200, null=True, blank=True)

通过这个查询,我可以得到这个艺术家的所有作品:

    works = PersonWorkPlace.objects.filter(person=self.kwargs['pk'])

如何进一步搜索同一艺术家在特定地点的相同“piece_type”作品的数量(计数)?

我想为特定视图传递或从上下文中提取以下信息:

艺术家 A 在 Place A 有 2 幅画作和 2 幅雕塑在 Place B 有 4 幅画作

'上下文':{(地点:'地点A',绘画:'2',雕塑:'2'),(地点:'地点B',绘画:'4')}

4

1 回答 1

0

您可以使用以下查询按地点获取艺术家的作品类型计数

Place.objects.filter(
    personworkplace__artist=artist
).values(
    'name',
    'personworkplace__work__piece_type'
).annotate(
    count=Count('personworkplace__work__piece_type')
)

返回的键之一是“personworkplace__work__piece_type”,它有点难看,您可以使用注释来更改它

Place.objects.filter(
    personworkplace__artist=artist
).annotate(
    piece_type=F('personworkplace__work__piece_type')
).values(
    'name',
    'piece_type'
).annotate(
    count=Count('piece_type')
)

编辑(下面的旧答案):

给定一个artist你可以使用这个查询来获取你想要的值

Place.objects.filter(
    personworkplace__artist=artist
).annotate(
    painting=Sum(Case(
        When(personworkplace__work__piece_type='painting', then=1),
        output_field=IntegerField()
    )),
    sculpture=Sum(Case(
        When(personworkplace__work__piece_type='sculpture', then=1),
        output_field=IntegerField()
    )),
).values('name', 'something', 'something_else')

Sum、Case、When 可用于根据条件对相关对象进行条件计数,这允许您按类型对特定作品进行计数

于 2019-09-08T00:34:12.433 回答