在笔者认为,在Django rest framework中最重要的是序列化组件,通过序列化我们可以将我们后台数据通过一定格式发送到我们的前端,然后通过一定的方法展示我们的数据。
那么我们就开始介绍我们的序列化组件吧!
自定义字段
url部分:
from django.conf.urls import url, include from web.views.s6_serializers import TestView urlpatterns = [ url(r'test/', TestView.as_view(), name='test'), ] urls.py
视图部分:
#!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import serializers from .. import models class PasswordValidator(object): def __init__(self, base): self.base = base def __call__(self, value): if value != self.base: message = 'This field must be %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 UserSerializer(serializers.Serializer): ut_title = serializers.CharField(source='ut.title') user = serializers.CharField(min_length=6) pwd = serializers.CharField(error_messages={'required': '密码不能为空'}, validators=[PasswordValidator('666')]) class TestView(APIView): def get(self, request, *args, **kwargs): # 序列化,将数据库查询字段序列化为字典 data_list = models.UserInfo.objects.all() ser = UserSerializer(instance=data_list, many=True) # 或 # obj = models.UserInfo.objects.all().first() # ser = UserSerializer(instance=obj, many=False) return Response(ser.data) def post(self, request, *args, **kwargs): # 验证,对请求发来的数据进行验证 ser = UserSerializer(data=request.data) if ser.is_valid(): print(ser.validated_data) else: print(ser.errors) return Response('POST请求,响应内容') views.py
基本用法:
from rest_framework import serializers class RolesSerializer(serializers.Serializer): id = serializers.IntegerField() #显示的顺序和这里的顺序有关 title = serializers.CharField() #我们需要的字段 class RolesView(APIView): def get(self,request,*args,**kwargs): #方式一 # roles = models.Role.objects.all().values('id','title') # roles = list(roles) # ret = json.dumps(roles,ensure_ascii=False)#序列化,改成False则显示中文,不帮中文编码 #方式二 对于querryset [obj,obj,obj] # roles = models.Role.objects.all() # ser = RolesSerializer(instance=roles,many=True)#有多条数据 many=True # # print(ser.data)#是一个有序的字典 # ret = json.dumps(ser.data, ensure_ascii=False) role = models.Role.objects.all().first() ser = RolesSerializer(instance=role, many=False) # 针对单个数据 # print(ser.data)#是一个有序的字典 ret = json.dumps(ser.data, ensure_ascii=False) return HttpResponse(ret)
各种字段连接关系的使用:
class UserInfoSerializer(serializers.Serializer): #类名和我们的orm没有硬性关系,但是最好是按照数据库的来这样能分清 user_type1 = serializers.CharField(source="user_type") user_type2 = serializers.CharField(source="get_user_type_display") username = serializers.CharField() password = serializers.CharField() gp = serializers.CharField(source='group.title') #通过.的方式去连外键 # like = serializers.CharField(source='roles.all ') 多对多的时候不能用这种方式,显示不出来 #--------------------------------------------# rls = serializers.SerializerMethodField() #多对多使用 def get_rls(self,row): role_obj_list = row.roles.all() #字段名 ret=[] for item in role_obj_list: ret.append({'id':item.id,'title':item.title}) return ret class UserInfoSerializer(serializers.ModelSerializer): #ModelSerializer相比上面的类更简洁 user_type2 = serializers.CharField(source="get_user_type_display") #实现自连,为什么实现 rls = serializers.SerializerMethodField() class Meta: model = models.UserInfo fields = ['id','username','password','user_type2','rls'] def get_rls(self, row): #自定义显示 role_obj_list = row.roles.all() #字段名 ret=[] for item in role_obj_list: ret.append({'id':item.id,'title':item.title}) return ret
深度控制以及反向生成URL
urls.py
urlpatterns = [ re_path(r'^(?P<version>[v1|v2]+)/userinfo/$', views.UserInfoView .as_view(),), re_path(r'^(?P<version>[v1|v2]+)/group/(?P<pk>d+)$', views.GroupView .as_view(),name='gp'), re_path(r'^(?P<version>[v1|v2]+)/group/(?P<pk>d+)$', views.GroupView .as_view(),name='gp'), ]
views.py
class UserInfoSerializer(serializers.ModelSerializer): group = serializers.HyperlinkedIdentityField(view_name='gp',lookup_field='group_id',lookup_url_kwarg='pk') class Meta: model = models.UserInfo fields = ['id','username','password','group','roles'] #fields是固定的变量,不能自定义 depth = 0 #深度控制 感觉是向后.一个单位, class UserInfoView(APIView): def get(self,request,*args,**kwargs): users = models.UserInfo.objects.all() ser = UserInfoSerializer(instance=users,many=True,context={'request':request}) ret = json.dumps(ser.data,ensure_ascii=False) #防止出现乱码,在序列化的时候添加这个 return HttpResponse(ret) class GroupSerializer(serializers.ModelSerializer): # group = serializers.HyperlinkedIdentityField(view_name='gp',lookup_field='group_id',lookup_url_kwarg='xxx') class Meta: model = models.UserGroup fields = '__all__' # fields = ['id','username','password','group','roles'] #fields是固定的变量,不能自定义 depth = 0 #深度控制 感觉是向后.一个单位, class GroupView(APIView): def get(self,request,*args,**kwargs): pk = kwargs.get('pk') obj = models.UserGroup.objects.filter(pk=pk).first() ser = GroupSerializer(instance=obj,many=False) ret = json.dumps(ser.data,ensure_ascii=False) return HttpResponse(ret)