简体   繁体   English

Django rest 框架——过滤多对多字段

[英]Django rest framework - filter many-to-many field

Suppose I have a model like this one:假设我有一个像这样的 model:

class Car(models.Model):
    images = models.ManyToManyField(Image)

class Image(models.Model):
    path = models.CharField()
    type = models.CharField()

I want to expose two API views:我想公开两个 API 视图:

  • cars list汽车清单
  • car details汽车细节

In list view I want to show only images that have type="thumbnail".在列表视图中,我只想显示 type="thumbnail" 的图像。 In details view I want to show images of type="image".在详细信息视图中,我想显示 type="image" 的图像。

This is more or less what the list should look like:这或多或少应该是列表的样子:

[{
    "id": 1,
    "images": [1, 2],
},
{
    "id": 2,
    "images": [3, 4],
}]

And the details view:和细节视图:

{
    "id": 1,
    "images": [5],
}

Note that different image ids are displayed depending on the view.请注意,根据视图显示不同的图像 ID。

So far my serializer looks like this:到目前为止,我的序列化程序如下所示:

class CarSerializer(serializers.ModelSerializer):
    images = serializers.ManyPrimaryKeyRelatedField()

    class Meta:
        model = Car

List api view:列表 api 查看:

class CarList(generics.ListAPIView):
    model = Car
    serializer_class = CarSerializer

Details api view:详情 api 查看:

class CarDetails(generics.RetrieveAPIView):
    model = Car
    serializer_class = CarSerializer

This of course gives me all images in list as well as in details and forces clients to make additional calls to get image type that should be displayed.这当然会为我提供列表中的所有图像以及详细信息,并迫使客户进行额外的调用以获取应显示的图像类型。

Is there any generic way to do it?有什么通用的方法吗? I have seen django-filter examples, but it seems that its only possible to filter which objects are listed, not what related objects in listed objects are listed.我看过 django-filter 示例,但似乎只能过滤列出了哪些对象,而不是列出了列出的对象中的哪些相关对象。

I don´t know if you are still looking for this answer, but maybe it helps someone else.我不知道你是否还在寻找这个答案,但也许它对其他人有帮助。

First create a filter class like this:首先创建一个像这样的过滤器类:

class CarFilter(django_filters.FilterSet):
    having_image = django_filters.Filter(name="images", lookup_type='in')

    class Meta:
        model = Car

Then add the filter to your view:然后将过滤器添加到您的视图中:

class CarList(generics.ListAPIView):
    model = Car
    serializer_class = CarSerializer
    filter_class = CarFilter

And that´s all.就这样。 Add "?having_image=1" to your query string and Django filter should do the trick for you.将 "?have_image=1" 添加到您的查询字符串中,Django 过滤器应该会为您解决问题。

Hope it helps..希望能帮助到你..

I have found a other Stackoverflow question that has a solution that could be used here:我发现了另一个 Stackoverflow 问题,它有一个可以在这里使用的解决方案:

How can I apply a filter to a nested resource in Django REST framework? 如何将过滤器应用于 Django REST 框架中的嵌套资源?

(see under the "Solution" headline in the question itself) (请参阅问题本身的“解决方案”标题下)

I came up with this solution:我想出了这个解决方案:
it's definitely not the optimized one but can be used for a quick fix or maybe for a hobby project.它绝对不是优化的,但可以用于快速修复或用于业余项目。

So after serializing all the applications, I loop over the data to get the required results, append it inside an array and send it back as response.所以在序列化所有应用程序之后,我循环数据以获得所需的结果,append 它在一个数组中并将其作为响应发送回来。

Models file:模型文件:

在此处输入图像描述

Views file:视图文件:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM