Django REST framework之序列化、解析器
Demo的目录结构:

DjWebApi2.urls文件:API路由分发
"""DjWebApi2 URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.1/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path,include from Api.views import demo urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('Api.urls')), path('demo/',demo.demo), ]
Api.url文件:API路由
from django.urls import path,re_path from Api.views import version,parserdemo,serializersdemo urlpatterns = [ # 版本demo re_path(r'^(?P<version>[v1|v2]+)/users/$', version.UsersView.as_view(), name='userspath'), # 解析器demo re_path(r'^(?P<version>[v1|v2]+)/parser/$', parserdemo.ParserView.as_view(), name='parserpath'), # 序列化demo re_path(r'^(?P<version>[v1|v2]+)/serializers/$', serializersdemo.UserinfoView.as_view(), name='serializerspath'), re_path(r'^(?P<version>[v1|v2]+)/group/(?P<gid>\d+)$', serializersdemo.GroupView.as_view(), name='gp'), re_path(r'^(?P<version>[v1|v2]+)/usergroup/$', serializersdemo.UserGroupView.as_view()), ]
settings.py:配置文件
REST_FRAMEWORK = { 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning', # /api/v1/users/ 版本配置 'DEFAULT_VERSION':'v1', # 默认版本 'ALLOWED_VERSIONS':['v1','v2'], # 可用版本 'VERSION_PARAM':'version', # 版本参数 'DEFAULT_PARSER_CLASSES':[ "rest_framework.parsers.JSONParser", # 仅处理请求头content-type为application/json的请求体 "rest_framework.parsers.FormParser", # 仅处理请求头content-type为application/x-www-form-urlencoded 的请求体 "rest_framework.parsers.MultiPartParser", # 仅处理请求头content-type为multipart/form-data的请求体 ], 'UNICODE_JSON': False, # 编码格式 }
version.py:版本demo
from django.shortcuts import render,HttpResponse from django.urls import reverse from rest_framework.views import APIView from rest_framework.request import Request # Create your views here. # 自定义 # class ParamVersion(BaseVersioning): # def determine_version(self, request, *args, **kwargs): # version = request.query_params.get('version') # return version class UsersView(APIView): def get(self,request,*args,**kwargs): print(request.version) # 获取版本 print(request.versioning_scheme) # 获取处理版本的对象 # rest_framework 反向生成url print(request.versioning_scheme.reverse(viewname='usersss',request=request)) # django 自带反向生成url print(reverse(viewname='userspath',kwargs={'version':request.version})) return HttpResponse('用户列表')
parserdemo.py:解析器demo
from django.shortcuts import render,HttpResponse from django.urls import reverse from rest_framework.views import APIView from rest_framework.request import Request class ParserView(APIView): def post(self,request,*args,**kwargs): ''' 运行用户发送JSON格式:可以支持请求头格式 a.content-type:application/json b.{'name':'alex','age':18} :param request: :param args: :param kwargs: :return: ''' print(request.data) # 获取请求的值,并使用对应的JSONParser进行处理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值 print(request.POST) print(request.FILES) return HttpResponse('解析器')
serializersdemo.py:序列化和验证
from django.shortcuts import render from django.http import JsonResponse from rest_framework.views import APIView from rest_framework import serializers from Api import models import json ##########################序列化########################## # 第一种方式 Serializer """ class Userinfoserializers(serializers.Serializer): # user_type = serializers.IntegerField() # 序列化后数据对应 "user_type": 1, xxxxx = serializers.CharField(source='user_type') # 序列化后数据对应 "user_type": "(('普通用户', 1), ('会员用户', 2), ('管理员', 3))", ooooo = serializers.CharField(source='get_user_type_display') username = serializers.CharField() password = serializers.CharField() gp = serializers.CharField(source='group.title') # ForeignKey使用group.title rls = serializers.SerializerMethodField() # 自定义函数显示 函数名:get_字段名称 def get_rls(self,row): # 获取所有角色对象 roles_list = row.roles.all() result = [] for item in roles_list: # 将角色对象id和title遍历出来 result.append({'id': item.id, 'title': item.title}) return result """ # 第二种方式 ModelSerializer class Userinfoserializers(serializers.ModelSerializer): # 反向生成url view_name:url别名 lookup_field: 数据库字段 lookup_url_kwarg:携带的参数/group/(?P<gid>\d+),参数可以任意命名 group = serializers.HyperlinkedIdentityField(view_name='gp',lookup_field='group_id',lookup_url_kwarg='gid') class Meta: model = models.UserInfo # fields = "__all__" fields = ['id','username','password','group','roles'] depth = 0 # 深度 官方建议0~10之间 class UserinfoView(APIView): def get(self,request,*args,**kwargs): response = {'status':False,'data':None} qdata = models.UserInfo.objects.all() ''' qdata --- QuerySet对象 instance --- QuerySet对象 many --- 多条数据True;单条数据Flase context={'request': request} --- 反向生成url时需要的参数 ''' ser = Userinfoserializers(instance=qdata,many=True,context={'request': request}) response['status'] = True response['data'] = ser.data return JsonResponse(response) class Groupserializers(serializers.ModelSerializer): class Meta: model = models.UserGroup fields = "__all__" class GroupView(APIView): def get(self,request,*args,**kwargs): pk = kwargs.get('gid') obj = models.UserGroup.objects.filter(pk=pk).first() ret = Groupserializers(instance=obj, many=False) return JsonResponse(ret.data) ##########################验证########################## class titleValidator(object): def __init__(self, base): self.base = str(base) def __call__(self, value): print(value) if value != self.base: message = '标题必须为666 %s.' % self.base raise serializers.ValidationError(message) def set_context(self, serializer_field): """ This hook is called by the serializer instance, prior to the validation call being made. """ # 执行验证之前调用,serializer_fields是当前字段对象 pass # 第一种验证方式 # class UserGroupserializers(serializers.Serializer): # """ # error_messages={'required':'标题不能为空'} === 验证不能为空 # validators=[xxxValidator(666), ] === 验证函数 # """ # title = serializers.CharField(error_messages={'required':'标题不能为空'},validators=[titleValidator(666), ]) class UserGroupserializers(serializers.ModelSerializer): title = serializers.CharField() # 钩子函数:validate_+字段名称 value:数据 def validate_title(self,value): from rest_framework import exceptions if value=='666': return value raise exceptions.ValidationError('title必须为666') class Meta: model = models.UserGroup fields = "__all__" class UserGroupView(APIView): def post(self, request, *args, **kwargs): res = UserGroupserializers(data=request.data) # res.is_valid() === 返回验证结果 if res.is_valid(): # 验证成功后的数据 result = res.validated_data else: # 验证失败返回的错误信息 result = res.errors return JsonResponse(result)

浙公网安备 33010602011771号