如何在Django中的同一MySQL查询集上实现order_by和group_by

时间:2019-05-14 13:21:48

标签: django python-3.x django-rest-framework django-views django-filter

我有一个Image模型和Resized_Image模型,在其中我将原始图像的大小调整为不同的大小,并将它们存储在Resized_Image模型中。当我尝试过滤数据时,它给出重复的结果。

这是我的模特:

class Image(models.Model):
    name=models.CharField(max_length=40,unique=True,help_text="name of the image")
    status = StatusField()

class Resized_image(models.Model):
    img = models.ForeignKey(Image, related_name='images', on_delete=models.CASCADE,)
    image=models.ImageField(upload_to=date_format,width_field='width', height_field='height',)
    width=models.PositiveIntegerField()
    height=models.PositiveIntegerField()

我的序列化器:

class resized_imagesSerializer(serializers.ModelSerializer):
    class Meta:
       model = Resized_image
       fields = ('image','width','height')

class imagesSerializer(QueryFieldsMixin,serializers.ModelSerializer):

   images =resized_imagesSerializer(many=True,required=False,read_only=True)
   image = Base64ImageField(write_only=True,)
   class Meta:
       model = Image
       fields = ('id','name','image','status','images')
       required = ['image']

我的观点:

class ImageListView(mixins.CreateModelMixin,generics.ListAPIView):
     queryset = Image.objects.all()
     serializer_class = imagesSerializer
     def get_queryset(self):
        param = self.request.query_params.get("width", None)
        queryset = Image.objects.order_by(*param) 

     return queryset

我的结果未经任何过滤:

{
    "id": 1,
    "name": "abc",
    "status": 0,
    "images": [
        {
            "id": 1,
            "image": "/images/photos/2019/04/29/14b77119-5d7.png",
            "width": 720,
            "height": 200
           },
        {
            "id": 2,
            "image": "/images/photos/2019/04/29/Movies/medium/14b77119-5d7.png",
            "width": 720,
            "height": 1280

        }
    ]
}

在这里,当我有多张图片,但它们的大小不同时,如果尝试按宽度排序,则会得到重复的结果(ID为1的图像重复两次)。如何使用Django在有序查询集上进行group_by。 我已经使用了注释,但是也给出了相同的结果。

Image.objects.order_by(*ordering).annotate(Count('id'))

1 个答案:

答案 0 :(得分:0)

尝试使用子查询

min_query =
    Resized_image.objects.filter(image_id=OuterRef('id'))
    .order_by('width')
    .values('width', 'height', 'image')[:1]

Image.objects.all().annotate(
    width=Subquery(
        min_query.values('width'))
    ).annotate(
    height=Subquery(
        min_query.values('height'))
    ).annotate(
    image=Subquery(
        min_query.values('image'))
    )