【django framework】ModelSerializer+GenericAPIView,如何在提交前修改某些字段值
我们经常会遇到下面这种情况:
序列化器用的是ModelSerializer ,写视图的时候继承的是generics.CreateAPIView。现在我想在正式提交到数据库(perform_create)之前,修改几个字段的值,应该怎么去做呢?
目录
- [【django framework】ModelSerializer+GenericAPIView,如何在提交前修改某些字段值](#【django framework】ModelSerializer+GenericAPIView,如何在提交前修改某些字段值)
- [1 在Serializer序列化器中重写create](#1 在Serializer序列化器中重写create)
- [2 继承generics.CreateAPIView后,重写perform_create()](#2 继承generics.CreateAPIView后,重写perform_create())
1 在Serializer序列化器中重写create
我们知道序列化器承担了部分视图的作用,但是它主要的作用有两个:
① 对序列化进来的数据进行校验,比如validate一下手机号格式是不是正确
② 写入一些默认或者不需要前端传递的字段// 如果说执意要在Serializer中写业务逻辑,也可以。只不过这种写法会和rest_framework的设计理念相违背,增加了序列化器和视图的耦合性。
python
from rest_framework import serializers
from .models import *
import re
class YourModelSerializer(serializers.ModelSerializer):
"""
YourModel 创建 序列化器
"""
class Meta:
model = YourModel
fields = '__all__'
def validate(self, kwargs):
"""
校验
校验前端传过来的用户手机号格式对不对
"""
MOBILE = kwargs.get('mobile').mobile
REGEX_MOBILE = '1[3475698]\d{9}$|^147\d{8}$|^176\d{8}|^198\d{8}$'
# 客户手机号格式
if not re.match(REGEX_MOBILE, MOBILE):
raise serializers.ValidationError("客户手机号格式有误")
return kwargs
def create(self, validated_data):
"""
重写create方法
// 添加唯一序列号
序列号不需要前端传递
"""
# 唯一序列号
validated_data['serial'] = 'serial102356478'
# 可以在此写业务逻辑,但是并不推荐
return super().create(validated_data)
2 继承generics.CreateAPIView后,重写perform_create()
秉承着谁的活由谁来干的原则,第一种方法虽然可行,但是增加了序列化器与视图之间的耦合性,所以并不是一个好方法。
所以我们通过重写perform_create()方法来修改我们想要修改的字段。
而视图本就是写业务逻辑的,这也符合rest_framework设计初衷。
python
from rest_framework import generics
from .models import YourModel
from .serializers import YourModelSerializer
class YourModelCreateAPIView(generics.CreateAPIView):
queryset = YourModel.objects.all()
serializer_class = YourModelSerializer
def perform_create(self, serializer):
# 获取需要修改的字段的值
some_field_value = serializer.validated_data.get('field_name')
# 修改字段的值
modified_field_value = some_field_value + '_modified'
# 更新字段的值
serializer.validated_data['some_field'] = modified_field_value
# 继续调用serializer的save方法保存对象
serializer.save()
如此,即完成了功能,又不破坏框架功能模块间的耦合性,而代码的质量也由此而提升,皆大欢喜。