2019-06-13 Django-Rest-Framework
参考文档:
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字段唯一,这个唯一有时候是不太可能的。