在序列化类中,如果想使用request,则可以通过self.context['request']获取
序列化器的主要由两大功能
- 对请求的数据进行校验(底层调用的是Django的Form和ModelForm)
- 对数据库查询的数据进行序列化
1.数据的校验
注意自定义的钩子函数中的参数value,对于FK或者M2M的字段,是一个对象而不是文本
1.1Serializer
基于Serializer类,类似Django中的Form
import re from rest_framework.views import APIView from rest_framework.views import Response from rest_framework import serializers from django.core.validators import EmailValidator class MyEmailValidator(object): def __init__(self, base): self.base = base def __call__(self, value): match_object = re.match(self.base, value) if not match_object: raise serializers.ValidationError('格式错误') class UserSerializer(serializers.Serializer): username = serializers.CharField(label='姓名', min_length=6, max_length=32) age = serializers.IntegerField(label='年龄', min_value=0, max_value=200) level = serializers.ChoiceField(choices=((1, '董事长'), (2, '经理'), (3, '员工'))) email1 = serializers.EmailField(label='邮箱1') email2 = serializers.CharField(label='邮箱2', validators=[EmailValidator, ]) email3 = serializers.CharField(label='邮箱3') email4 = serializers.CharField(label='邮箱4', validators=[MyEmailValidator(r"^w+@\w+\.\w+$")]) def validate_email3(self, value): "钩子函数" if not re.match(r"^w+@\w+\.\w+$", value): raise serializers.ValidationError('格式错误') return value class User(APIView): def get(self, request): return Response({'code':0, 'data':'创建成功'}) def post(self, request): ser = UserSerializer(data=request.data) if not ser.is_valid(): return Response({'code':1006, 'data':ser.errors}) print(ser.validated_data) return Response({'code':0, 'data':'创建成功'})
1.2 ModelSerializer
基于ModelSerializer类,类似Django中的ModelForm
import re from rest_framework.views import APIView from rest_framework.views import Response from rest_framework import serializers class UserModelSerializer(serializers.ModelSerializer): class Meta: model = UserInfo # fields = '__all__' fields = ['username', 'age', 'email', 'password', 'level', 'depart', 'roles'] class User(APIView): def get(self, request): return Response({'code': 0, 'data': '创建成功'}) def post(self, request): ser = UserModelSerializer(data=request.data) if not ser.is_valid(): return Response({'code': 1006, 'data': ser.errors}) ser.save() print(ser.validated_data) return Response({'code': 0, 'data': '创建成功'})
2.序列化
通过ORM从数据库中获取QuerySet或者对象,然后序列化为json格式的数据
模型类
from django.db import models # Create your models here. class Role(models.Model): title = models.CharField(verbose_name='名称', max_length=32) class Department(models.Model): title = models.CharField(verbose_name='名称', max_length=32) class UserInfo(models.Model): level_choices = ((1, '普通会员'), (2, 'VIP'), (3, 'SVIP')) level = models.IntegerField(verbose_name='级别', choices=level_choices, default=1) username = models.CharField(verbose_name='用户名', max_length=32) password = models.CharField(verbose_name='密码', max_length=32) age = models.IntegerField(verbose_name='年龄', default=18) email = models.CharField(verbose_name='邮箱', max_length=64) token = models.CharField(verbose_name='TOKEN', max_length=64, null=True, blank=True) depart = models.ForeignKey(verbose_name='部门', to='Department', null=True, blank=True, on_delete=models.CASCADE) roles = models.ManyToManyField(verbose_name='角色', to="Role")
2.1 基本使用
-
序列化的是一个queryset,则many=True
-
序列化的是一个对象,则many=False
视图类
from rest_framework.views import APIView from rest_framework.views import Response from rest_framework import serializers from web.models import UserInfo class UserModelSerializer(serializers.ModelSerializer): class Meta: model = UserInfo fields = ['username', 'age', 'email'] class User(APIView): def get(self, request): """获取用户列表""" queryset = UserInfo.objects.all() ser = UserModelSerializer(instance=queryset, many=True) return Response({'code': 0, 'data': ser.data})
2.2 自定义字段
-
将数据库中的choice字段显示中文,如level_text
-
将ForeignKey字段显示,如depart
-
自定义字段,如extra,
-
如果类中自定义的字段名和数据库的一样,则覆盖掉数据库的字段,如depart
extra = serializers.SerializerMethodField() def get_extra(self,obj): return 666
1 from rest_framework.views import APIView 2 from rest_framework.views import Response 3 from rest_framework import serializers 4 from django.core.validators import EmailValidator 5 6 from web.models import UserInfo, Department, Role 7 8 9 class UserModelSerializer(serializers.ModelSerializer): 10 level_text = serializers.CharField(source="get_level_display") 11 depart = serializers.CharField(source="depart.title") 12 13 14 extra = serializers.SerializerMethodField() 15 class Meta: 16 model = UserInfo 17 fields = ['username', 'age', 'email', 'level_text', 'depart', 'extra'] 18 19 20 def get_extra(self,obj): 21 return 666 22 23 24 class User(APIView): 25 def get(self, request): 26 """获取用户列表""" 27 28 queryset = UserInfo.objects.all() 29 ser = UserModelSerializer(instance=queryset, many=True) 30 return Response({'code': 0, 'data': ser.data})
2.3 序列化的嵌套
在一个序列化类中,可以嵌套另外一个序列化类
视图
import re from rest_framework.views import APIView from rest_framework.views import Response from rest_framework import serializers from django.core.validators import EmailValidator from web.models import UserInfo, Department, Role class DepartModelSerializer(serializers.ModelSerializer): class Meta: model = Department fields = '__all__' class RoleModelSerializer(serializers.ModelSerializer): class Meta: model = Role fields = '__all__' class UserModelSerializer(serializers.ModelSerializer): depart = DepartModelSerializer() roles = RoleModelSerializer(many=True) class Meta: model = UserInfo fields = ['username', 'age', 'email', 'depart', 'roles'] class User(APIView): def get(self, request): """获取用户列表""" queryset = UserInfo.objects.all() ser = UserModelSerializer(instance=queryset, many=True) return Response({'code': 0, 'data': ser.data})
3.数据校验&序列化
有时候我们的序列化类可能既要序列化数据,也要校验数据,并且这是常有的,我们就需要给字段设置只读,只写或者可读可写来决定某个字段在序列化或者校验时是否使用本身
- read_only= True
- write_only = True
- 即可读也可写
注意:
如果有嵌套的Serializer,在进行数据校验时,只有两种选择:
1. 将嵌套的序列化设置成 read_only
2. 自定义create和update方法,自定义新建和更新的逻辑
4.源码分析
4.1 类的定义
4.2 序列化
4.3 数据检验
4.4 数据保存
标签:serializers,models,import,序列化,data,class,drf From: https://www.cnblogs.com/victor1234/p/16891710.html