validate_{field_name}
,这个方法只有在当前的序列化器定义了这个字段时才会管用,如果直接在Meta里面指定的字段,那么它是不会被调用的,这时候只有在validate
方法里面验证所有的字段class UtilsDispatch(object):
def dispatch(self, request, *args, **kwargs):
# 一般都是获取response.data来作为返回对象,思路为将response的data封装返回
response = super().dispatch(request, *args, **kwargs)
# 这里可以通过response的状态码来进行不同的封装
status_code = response.status_code
# 自定义不同状态码的响应函数
handle_method = getattr(self, 'handle_%d_method' % status_code, None)
# return handle_method(request, response, *args, **kwargs) if handle_method is not None else response
if handle_method:
# 将响应和请求一并传入自定义的处理函数,方便调用和转换
return handle_method(request, response, *args, **kwargs)
return response
# 简单定义一个响应创建成功的函数
def handle_201_method(self, request,response, *args, **kwargs):
# 将自定义的响应信息更新到response.data里面,返回response,前面就可以获取到自定义的响应信息了
response.data.update({'success': Ture, 'msg': '创建成功!'})
return response
request.data
视图默认将request.data传递到序列化器,但是request.data是不可更改的属性,这个时候可以将request.data copy 一份,拿到copy后的对象,将需要传递的参数更新到copy对象中,再将copy的对象传入序列化器
data = deepcopy(request.data)
item = {'current_user': request.user}
data.update(item)
serializer = Serializer(data=data)
传递的参数可以在序列化器中的initial_data
中获取initial_data
和上述思路一样,可以将需要传递的信息传递到initial_data里面
```python
serializer = Serializer(data=request.data)
item = {'current_user': request.user}
serializer.initial_data.update(item)
```
context
rest框架在调用get_serializer
方法的时候回去调用get_serializer_context
,这个方法会将reuqtes
、format
、view
这三个参数到序列化器的context中,而视图中的大部分参数都可以通过这三个参数获取到,所有可以直接在序列化器中self.context中直接获取视图中参数。(如果重写了action方法,若没有调用父类的get_serializer
,则不会将这个三个参数传递到序列化器中)
上面说到的默认字段可以通过self.context来获取,有些字段其实可以直接被隐藏
class BaseContext(object):
# 定义基类
def set_context(self, serializer_field):
# get request from context
self.request = serializer_field.context['request']
class CurrentUserDefault(BaseContext):
# 继承Base基类,实现call方法
def __call__(self):
return self.request.user
class DetailSerializer(ModelSerializer):
# 直接将这个字段隐藏,默认为当前的用户,可以不用自定义来处理,序列化器自动将当前的用户赋值给这个字段
user = serializers.HiddenField(default=CurrentUserDefault())
......
重写get_queryset
方法
def get_queryset(self):
# 根据request来定制查询
return super().get_queryset().filter(user=self.request.user)
serializer_class
,但又不想在写一个视图,这时候就要根据不同的请求来调用不同的序列化器了直接看源码很清楚,框架是默认调用类制定的serializer_class
,如果想定制,就得重写get_serializer_class
class YourViewSet(ModelViewSet):
# balabala
serializer_class_route = {
'list': xxxx,
'create': xxxx,
}
def get_serializer_class(self, *args, **kwargs):
if hasattr(self, 'serializer_class_route'):
return self.serializer_class_route.get(self.action)
return super().get_serializer_class(*args, **kwargs)
class XXXX(ModelViewSet):
# balabala
filterset_fields = [field1, field2, .....]
原文:https://www.cnblogs.com/ivy-blogs/p/11994124.html