2019-06-13 Django-Rest-Framework 序列化 manytomany

参考文档:
https://medium.com/@chriziegler/slugrelatedfield-with-django-and-the-rest-framework-36717b07a197
https://www.vinta.com.br/blog/2018/django-rest-framework-read-write-serializers/
https://www.django-rest-framework.org/api-guide/relations/#slugrelatedfield

在使用 DRF 开发前后端分离系统的时候,需要对外展示 ManyToMany 数据关系的时候,遇见了问题。首先看一下需求:当前后端分离的之后具有 ManyToMany 的属性就需要展示和编辑(writable),所以 DRF 文档上面部分封装好的 Readonly 的 serializers 就失去了作用。
我们需要的数据:

{
    "count": 1,
    "next": "http://localhost:5000/api/xxx/?page=2",
    "previous": null,
    "page": 1,
    "results": [
        {
            "id": 11,
            "creator": "admin",
            "sample_type": [
                "全血",
                "测试样本"
            ],
            "test_product": [],
        }
    ]
}

如果使用 sample_type 的 SampleTypeSerializer(many=True) ,由于序列化和反序列化需求,前端需要提交上来 sample_type 对象,比较麻烦不过也不失为一种办法。
DRF 也提供了多种方法供使用:

sample_type = serializers.SlugRelatedField(many=True, slug_field='name', queryset=SampleType.objects.all(), allow_null=True)

我就采用了这种方法(同参考文献1),弊端是要求 slug_field 的字段唯一, 而且前端提交也是这个字段才可以正常添加。

如果使用 HyperlinkedRelatedField 前后端交互就得到的是资源link,而且也需要提交资源link,既不利于展示(前端还要再做解析)又不利于提交。

如果使用 PrimaryKeyRelatedField 前后端交互就得到的是资源id,而且也需要提交资源id,也是既不利于展示(前端还要再做解析)又不利于提交。

还有一种思路是在 models 里面增加一个属性字段

    @property
    def sample_type(self):
        sts = self.sample_type.objects.all()
        return sts['name']

在序列化中指定 只读和显示, 此字段专门用于前端显示,而交互使用 PrimaryKeyRelatedField, 每次提交id列表即可。

后来想一下,最靠谱的还是使用 SampleTypeSerializer, 虽然交互都是 object 但是解析和显示还是比较清晰的,而且没有额外限制name字段唯一,这个唯一有时候是不太可能的。

你可能感兴趣的:(2019-06-13 Django-Rest-Framework 序列化 manytomany)