Django rest framework - 过滤多对多字段

5
假设我有一个这样的模型:
class Car(models.Model):
    images = models.ManyToManyField(Image)

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

我希望暴露两个API视图:

  • 汽车列表
  • 汽车详细信息

在列表视图中,我只想显示类型为“缩略图”的图像。 在详细视图中,我想显示类型为“图像”的图像。

以下大致是列表应该看起来的样子:

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

以及详细信息视图:

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

请注意,不同的图像ID会根据视图显示。
到目前为止,我的序列化器看起来是这样的:
class CarSerializer(serializers.ModelSerializer):
    images = serializers.ManyPrimaryKeyRelatedField()

    class Meta:
        model = Car

列表 API 视图:

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

详情API视图:

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

当然,这会给我所有列表中的图像以及详细信息,并迫使客户端进行额外的调用以获取应显示的图像类型。
有没有通用的方法来解决这个问题?我已经看过django-filter的例子了,但似乎只能过滤哪些对象被列出,而不能过滤列出对象中的相关对象。

你成功筛选出相关的对象了吗?我也在尝试同样的事情,但是没能让它工作。 - Anton
没有,但是我使用了一种解决方法,即嵌套图像对象而不是显示ID列表,这样客户端就不需要进行额外的调用 - 所有信息都已经存在。在此处阅读更多信息:http://django-rest-framework.org/api-guide/serializers.html#dealing-with-nested-objects - Jacek Chmielewski
嗨@Jacek!我找到了一个可能适用于你的问题的解决方案。请查看下面的答案。 - Anton
3个回答

7
我不知道您是否还在寻找答案,但也许能帮到其他人。
首先创建一个像这样的过滤器类:
class CarFilter(django_filters.FilterSet):
    having_image = django_filters.Filter(name="images", lookup_type='in')

    class Meta:
        model = Car

然后将过滤器添加到你的视图中:
class CarList(generics.ListAPIView):
    model = Car
    serializer_class = CarSerializer
    filter_class = CarFilter

就是这些了。在你的查询字符串中添加“?having_image=1”,Django过滤器就可以为您完成这个技巧。

希望这有所帮助。


4
这并不完全是原始用户所询问的内容。 - Zach Zundel

1

0
我想出了这个解决方案:
它肯定不是最优化的,但可以用于快速修复或者作为一个爱好项目。
因此,在序列化所有应用程序之后,我循环遍历数据以获取所需结果,将其附加在数组中,并将其作为响应发送回来。
模型文件:

enter image description here

视图文件:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接