补充 配置文件中的 类的调用:
(字符串) v1 = ["view.xx.apth.Role","view.xx.apth.Role"] for item in v1: m = importlib.import_module('view.xx.apth') cls = getattr(m,'Role') cls()
1 版本控制
一般是全局的 配置
1 基于 参数版本控制
versioning_class = QueryParameterVersioning # 默认参数是 version version = request.version # 获取到参数会放置在 request中
2 基于 url 版本控制
versioning_class = URLPathVersioning url 规则 (?P < version > [v1 | v2] +) print(request.versioning_scheme.reverse(viewname='api:user', request=request)) 这里可以通过request.versioning_scheme.reverse 进行url 反向解析 >> http: // 127.0.0.1: 8000 / api / v2 / user /
3 基于 host域名 版本控制
versioning_class = HostNameVersioning http: // v1.bpple.com: 8000 / api / user /
4 当然 可以 配置到 全局中 和 视图
'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.HostNameVersioning' ‘VERSION_PARAM’:‘version 'ALLOWED_VERSIONS':['v1','v2'] 'DEFAULT_VERSION':'v1'
2 解析器
Django 的 数据解析
在 django 中,满足如下两个条件时候 1 请求头中 Content-Type : application/x-www-form-urlencoded, 2 数据格式: name=alex&age=18 request.POST 中才有值 比如 form 表单提交 满足 1,2 ajax 提交的时候也是默认 1,2 条件 当然可以定义 ajax 发送的请求头和数据格式: headers:{'Content-Type':'application/json'} data:JSONstringfy({name:'aaa',age:12}) 这时候 后台 request.POST 中不再有数据 可以从 request.BODY 中获取数据
restfuframelwork对数据的解析 - 请求体进行解析
注意:只有使用 request.data的时候,parser对象才调用 #如果客户端的Content-Type的值和 application/json 匹配:JSONParser处理数据 #如果客户端的Content-Type的值和 application/x-www-form-urlencoded 匹配:FormParser处理数据 1 获取用户的请求 2 获取用户的请求体 3 根据用户的请求头 和 parser_classes 中支持的 parser 进行比较 4 parser对象 去请求 5 request.data
视图级别配置
class GoodsVieW(APIView): parser_classes = [JSONParser,FormParser] #表示服务端可以解析的数据格式的种类。 def post(self,request,*args,**kwargs): #必须要调用才能启动解析器,然后解析器先判断content-type, #如果和解析器要解析数据的类型一致,那么开始解析返回数据。 request.data #如果客户端的Content-Type的值和 application/json 匹配:JSONParser处理数据 #如果客户端的Content-Type的值和 application/x-www-form-urlencoded 匹配:FormParser处理数据
全局配置
全局配置,简称全配: settings.py中: REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES':[ 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', ] }
3 序列化
rest_framework 序列化 -- 更好的使用queryset
对象 -->> 字符串 序列化 字符串 -->> 对象 反序列化
1 基本实现
序列化的模板 class UserSerializer(serializers.Serializer): name = serializers.CharField() pwd = serializers.CharField() 多个 user_list = UserInfo.objects.all() ser = UserSerializer(user_list,many=True) 单个对象 user = UserInfo.objects.all().first() ser = UserSerializer(user,many=False) 返回 return Response(ser.data)
2 跨表处理
serializer class UserSerializer(serializers.Serializer): name = serializers.CharField() pwd = serializers.CharField() group_id = serializers.CharField() group_title = serializers.CharField(source='group.title') choices = serializer.CharField(source='get_type_display') menu_id = serializers.CharField(source='group.menu_id') menu_name = serializers.CharField(source='group.menu.name') model class Menu(models.Model): name = models.CharField(max_length=32) class Group(models.Model): title = models.CharField(max_length=32) menu = models.ForeignKey(to='Menu',default='1') class UserInfo(models.Model): name = models.CharField(max_length=32) pwd = models.CharField(max_length=32) group = models.ForeignKey(to='Group')
3 ModelSerializer
基本使用
class UserSerializer(serializers.ModelSerializer): class Meta: model = UserInfo # fields = ('name','pwd',) fields = '__all__'
modelserializer的嵌套
user 表的外键 group ,group的外键 menu class MenuSerializer(serializers.ModelSerializer): class Meta: model = Menu fields = '__all__' class GroupSerializer(serializers.ModelSerializer): menu = MenuSerializer() class Meta: model = Group fields = '__all__' class UserSerializer(serializers.ModelSerializer): group = GroupSerializer() # 通过外键直接关联实例化的对象 class Meta: model = UserInfo # fields = ('name','pwd',) fields = '__all__' --------------------------------------------------------------------------------------------------------------- 等同于 class UserSerializer(serializers.ModelSerializer): class Meta: model = UserInfo fields = '__all__' depth = 2 默认是0 只有表层 ,指定深度会拿出所有的关联 | 不超过10层
补充:
1 select的显示 get 字段 display
serializer.CharField(source='get_user_type_display')
2 通过 SerializerMethodField() # 自定义显示字段
def get_xxx(self,row): return row
3 # modelserializer 自动关联数据表
class UserInfoSerializer(serializers.ModelSerializer): info = serializers.CharField(source='get_user_type_display') roles = serializers.SerializerMethodField() def get_roles(self,row): return [{obj.id:obj.title} for obj in row.role.all()] class Meta: model = UseInfo fields = ['id','username'] extra_kwargs = { 'group':{'source':'gourp.title'} }
4 自定义 field 类 字段
class MyField(serializers.CharField): def to_representation(self, value): return '{0}***'.format(value) class Serializer_(serializers.Serializer): username = serializers.CharField(error_messages={'required':'请输入姓名'},validators=[MyValidator]) pwd = MyField()
5 生成连接
url(r'^api/(?P<version>[v1|v2]+)/(?P<pk>\d+)/',UserGroupView.as_view(),name='group') class UserInfoSerializer(serializers.Serializer): group = serializers.HyperlinkedIndentityField(view_name='group',lookup_id='group.id',lookup_url_kwarg='') class Meta: model = UserInfo fields = '__all__' class UserInfoView(APIView): obj = UserInfo.objects.get(...) ser = UserInfoSerializer(instance=obj,many=False,context={"request":request}) return JsonResponse(ser.data)
6 自定义validator
class MyValidator(object): def __init__(self,base): self.base = base def __call__(self, value): if not value.startswith(self.base): msg = '情以%s 开头'% self.base raise exceptions.ValidationError(msg, code='unique') class Serializer_(serializers.Serializer): username = serializers.CharField(error_messages={'blank':'请输入姓名'},validators=[MyValidator('he')])
7 自定义 钩子 validate_field
class Serializer_(serializers.Serializer): username = serializers.CharField(error_messages={'blank':'请输入姓名'},validators=[MyValidator('he')]) pwd = serializers.CharField() def validate_pwd(self,value): if not value.startswith('123'): raise exceptions.ValidationError('密码情以123开头', code='unique') return value { "pwd": [ "密码情以123开头" ] }
8 全局钩子
def validate(self, value): if value.get('pwd') == value.get('repwd'): return value raise exceptions.ValidationError('两次密码不一致') { "non_field_errors": [ "两次密码不一致" ] }
来源:https://www.cnblogs.com/wind1024/p/9948430.html