【问题标题】:django orm latest item group by each foreign keydjango orm 每个外键的最新项目组
【发布时间】:2017-09-27 07:43:13
【问题描述】:

我们有以下型号:

class Publisher(models.Model):
    name = models.CharField(max_length=32)
    local_name = models.CharField(max_length=32)
    url_pattern = models.CharField(max_length=128)
    enabled = models.BooleanField(default=True)
    home_page = models.BooleanField(default=False)
    category = models.ForeignKey(NewspaperCategory, null=True)


class Newspaper(models.Model):
    class Meta:
        unique_together = ("publisher", "date")
        ordering = ("-date",)

    publisher = models.ForeignKey(Publisher)
    image = models.ImageField(upload_to=newspaper_upload_to)
    thumbnail = models.ImageField(upload_to=newspaper_thumbnail_upload_to)
    date = models.DateField()

我有一个APIView(Django rest 框架),并且有几个不同的查询参数可以过滤 API 的输出。我想要一个“最新”查询参数,它只列出每个发布者的最新版本。此外,在评估之前,我需要能够对 QuerySet 进行进一步的过滤和切片。

但是查询的结果应该是报纸实例而不是dict,所以我可以将它们提供给我的序列化程序。 我现在的看法是这样的:

class Newspapers(APIView):
    def get(self, request):

        queryset = models.Newspaper.objects.filter(deleted=False).prefetch_related('publisher')
        if "latest" in request.GET:
            # doing something here with queryset            
        if "publisher_id" in request.GET:
            queryset = queryset.filter(publisher_id=request.GET['publisher_id'])
        if "category" in request.GET:
            queryset = queryset.filter(publisher__category_id=request.GET['category'])
        if "before" in request.GET:
            queryset = queryset.filter(date__lt=request.GET['before'])
        if "after" in request.GET:
            queryset = queryset.filter(date__gte=request.GET['after'])
        if "home_page" in request.GET:
            queryset = queryset.filter(publisher__home_page=request.GET['home_page'].lower() == 'true')
        queryset = queryset.order_by('-date', 'publisher__order')
        return PagingResponse(
            request,
            serializers.NewspaperVersionSerializer,
            query=queryset,
            identifier_name='date'
        )

【问题讨论】:

  • 您可以在帖子中添加您已经尝试过的任何尝试吗?
  • @Ben 是的,我刚刚添加了

标签: django python-3.x django-orm


【解决方案1】:

我们可以通过两个查询来做到这一点:

        if "latest" in request.GET:
            latest_ids = list(  # <-- first query
                           queryset.order_by('id') 
                          .values('publisher_id')
                          .annotate(id=Max('id'))
                          .values_list('id', flat=True)
                          )
            queryset = queryset.filter(id__in=latest_ids) # <-- second query

第一个查询按出版商获取最新报纸组的列表,第二个查询获取这些报纸的查询集以进行进一步过滤、切片和...

【讨论】:

    猜你喜欢
    • 2019-10-11
    • 2018-08-28
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 2020-05-04
    • 2019-04-26
    • 1970-01-01
    相关资源
    最近更新 更多