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

Jac*_*ski 5 django django-rest-framework

假设我有一个这样的模型:

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

class Image(models.Model):
    path = models.CharField()
    type = models.CharField()
Run Code Online (Sandbox Code Playgroud)

我想公开两个 API 视图:

  • 汽车清单
  • 汽车详情

在列表视图中,我只想显示 type="thumbnail" 的图像。在详细信息视图中,我想显示 type="image" 的图像。

这或多或少是列表的样子:

[{
    "id": 1,
    "images": [1, 2],
},
{
    "id": 2,
    "images": [3, 4],
}]
Run Code Online (Sandbox Code Playgroud)

和详细信息视图:

{
    "id": 1,
    "images": [5],
}
Run Code Online (Sandbox Code Playgroud)

请注意,根据视图显示不同的图像 ID。

到目前为止,我的序列化程序如下所示:

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

    class Meta:
        model = Car
Run Code Online (Sandbox Code Playgroud)

列出 api 视图:

class CarList(generics.ListAPIView):
    model = Car
    serializer_class = CarSerializer
Run Code Online (Sandbox Code Playgroud)

详细api视图:

class CarDetails(generics.RetrieveAPIView):
    model = Car
    serializer_class = CarSerializer
Run Code Online (Sandbox Code Playgroud)

这当然为我提供了列表中的所有图像以及详细信息,并强制客户端进行额外调用以获取应显示的图像类型。

有没有通用的方法来做到这一点?我看过 django-filter 示例,但似乎只能过滤列出的对象,而不是列出列出的对象中的相关对象。

小智 6

我不知道你是否还在寻找这个答案,但也许它对其他人有帮助。

首先创建一个像这样的过滤器类:

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

    class Meta:
        model = Car
Run Code Online (Sandbox Code Playgroud)

然后将过滤器添加到您的视图中:

class CarList(generics.ListAPIView):
    model = Car
    serializer_class = CarSerializer
    filter_class = CarFilter
Run Code Online (Sandbox Code Playgroud)

就这样。将 "?have_image=1" 添加到您的查询字符串中,Django 过滤器应该会为您解决问题。

希望能帮助到你..

  • 这不是原始用户所要求的。 (2认同)

Ant*_*ton 1

我发现了另一个 Stackoverflow 问题,它有一个可以在这里使用的解决方案:

如何将过滤器应用于 Django REST 框架中的嵌套资源?

(参见问题本身的“解决方案”标题)