【问题标题】:How to use .annotate() or .aggregate() to extract a count from Django QuerySet relations?如何使用 .annotate() 或 .aggregate() 从 Django QuerySet 关系中提取计数?
【发布时间】:2020-01-09 18:33:12
【问题描述】:

我有以下 .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 幅画

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

【问题讨论】:

    标签: django django-models django-queryset django-aggregation django-annotate


    【解决方案1】:

    我不认为我会设置这样的模型,但也许是有原因的。这就是我想出的:

    from django.db.models import Count    
    from .models import PersonWorkPlace, Work
    
    artist_pk = 1
    
    artist_places = PersonWorkPlace.objects \
                        .filter(artist__pk=artist_pk) \
                        .order_by('place') \
                        .values('artist', 'place') \
                        .annotate(works=Count('work')) \
                        .values_list('artist', 'place', 'place__name', 'artist__name')
    
    if artist_places:
        print(artist_places[0][3])
        for place in artist_places:
            pieces = Work.objects \
                .filter(place__artist__pk=place[0], place__place__pk=place[1]) \
                .order_by('piece_type').values('piece_type') \
                .annotate(count=Count('piece_type'))
            print(artist_places[0][2], pieces)
    

    【讨论】:

      猜你喜欢
      • 2019-01-15
      • 2020-04-13
      • 2019-12-28
      • 2011-04-18
      • 2012-03-31
      • 2022-06-12
      • 2016-10-31
      • 2018-09-19
      • 2020-01-19
      相关资源
      最近更新 更多