zoukankan      html  css  js  c++  java
  • djangoRestFrameWork的小知识

    djangoRestFrameWork的小知识

    重写序列化器的save方法

    • 有时候,.create()和.update()方法名称可能没有意义。例如,在联系表格中,我们可能没有创建新实例,而是发送了电子邮件或登录(登录的时候用户名是唯一的,重写create方法来登录会报用户名已存在的错误)时,这时候可以直接重写save方法来完成相关的操作。

    验证器

    • 单独字段验证方法默认为validate_{field_name},这个方法只有在当前的序列化器定义了这个字段时才会管用,如果直接在Meta里面指定的字段,那么它是不会被调用的,这时候只有在validate方法里面验证所有的字段

    封装返回信息

    • 返回的response是由框架的dispatch方法返回的,这时候我们可以写一个mixin来封装框架的dispatch方法。
    • 使用mixin的好处是既可以不修改原来的处理逻辑和修改代码,还能对返回结果做一层封装
    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
    
    • 对需要实现自定义的视图类继承这个mixin类即可。

    视图传参到序列化器

    • 对于有些默认的字段前端不会传递,但需要获取的,比如当前的用户,就需要将request.user传递到序列化器

    • 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,这个方法会将reuqtesformatview这三个参数到序列化器的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())
      	......
      

    定制查询对象

    • 类原始的queryset对象因为拿不到任何的参数,所有很难根据当前的请求来进行filter查询

    • 重写get_queryset方法

      def get_queryset(self):
      	# 根据request来定制查询
      	return super().get_queryset().filter(user=self.request.user)
      

    定制serializer_class

    • 有时候不同的请求不想使用类里面的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)
      

    django_filter查询

    • django_filter是一个很好的查询工具,安装好之后可以在类里面直接定义一个查询的属性,而不用去创建一个filter对象类就可以完成查询功能

      class XXXX(ModelViewSet):
      	# balabala
      	filterset_fields = [field1, field2, .....]
      

    删除自动生成路由的url末尾的小斜杠

    • 与 SimpleRouter 一样,通过在实例化 DefaultRouter 时将 trailing_slash 参数设置为 False,可以删除 URL 路径上的尾部斜杠。

      router = DefaultRouter(trailing_slash=False)
      
  • 相关阅读:
    .NET实现图片切割效果(带拖放、缩放效果)
    合成艺术字二 :使用的透明类以及所用的颜色选择器JS(完整事列源码)
    Ajax.net中的Web服务
    IE6和IE7共存方法 (转)
    sql取不重复多字段
    CSS完美兼容IE6/IE7/FF的通用方法
    发布事件.net框架程序设计
    const和readonly
    CSS网站实用技巧:wordwrap同wordbreak的区别
    FCKeditor 2.1.1在ASP.NET中的设置和使用(转)
  • 原文地址:https://www.cnblogs.com/ivy-blogs/p/11994124.html
Copyright © 2011-2022 走看看