drf序列化与反序列化
序列化:
Model类对象转换为字符串用于传输
反序列化:
字符串转换为Model类对象用于使用
模型表:
from django.db import models class User(models.Model): CHOICE_SEX = ( (0, '男'), (1, '女') ) name = models.CharField(max_length=32, verbose_name='姓名') password = models.CharField(max_length=64, verbose_name='密码') sex = models.SmallIntegerField(choices=CHOICE_SEX, default=0) #如果是CharField类型上面就是‘0’,‘1’ create_time = models.DateTimeField(auto_now_add=True, blank=True)
is_delete = models.BooleanField(default=False) class Meta: db_table = 'o_user' #自定义创建的表名 verbose_name = '用户' #admin界面中显示的表面与表名复数形式 verbose_name_plural = verbose_name def __str__(self): return self.name
序列化类(序列化和反序列化都可以使用)
from rest_framework import serializers from .models import User class UserSerializer(serializers.Serializer): name = serializers.CharField(label='姓名', max_length=32, min_length=3, error_messages={ 'max_length': '姓名太长', 'min_length': '姓名太短' }) password = serializers.CharField(label='密码', max_length=64, min_length=3, error_messages={ 'max_length': '密码太长', 'min_length': '密码太短' }) sex = serializers.IntegerField(write_only=True) #1. write_only=True 只有反序列化才使用该字段,其他不使用 gender = serializers.SerializerMethodField(read_only=True) #2.可以自定义字段,并且read_only=True只有序列化才使用该字段,其他不使用 def get_gender(self, obj): # obj为参与序列化的Model类对象 return obj.get_sex_display() # 该函数的返回值就作为对应自定义数据序列化后的值 create_time = serializers.DateTimeField(required=False, write_only=True) #3.序列化与反序列化都不使用: a.注释 b.required=False(不参与反反序列化校验), write_only=True re_password = serializers.CharField(label='确认密码', max_length=64, min_length=3, write_only=True, error_messages={ #4.为全局校验钩子新增自定义校验字段 'max_length': '确认密码太长', 'min_length': '确认密码太短' }) def create(self, validated_data): # 5.反序列化重写save内部方法(为post接口提供新增Model类对象的功能) return User.objects.create(**validated_data) # 返回值:Model类要新增的对象 def update(self, instance, validated_data): # 反序列化重写save内部方法(为put接口提供更新Model类对象的功能) instance.update(**validated_data) return instance # 返回更新后的instance # 局部钩子 def validate_sex(self, value): if value not in (0, 1): raise serializers.ValidationError('未知性别') return value # 全局钩子 def validate(self, attrs): re_password = attrs.pop('re_password') password = attrs.get('password') if re_password != password: raise serializers.ValidationError('二次密码不一致') return attrs
视图类
from rest_framework.views import APIView from rest_framework.response import Response from .models import User from .serializers import UserSerializer class UsersAPIView(APIView): def get(self, request, *args, **kwargs) # 获取所有资源 | 单个资源 pk = kwargs.get('pk', None) if not pk: user_query = User.objects.filter(is_delete=False).all() else: user_query = User.objects.filter(is_delete=False, pk=pk) user_data = UserSerializer(instance=user_query, many=True).data #如果只操作一个对象,many参数需要为False(默认值),如果是列表之类的需要设置为True return Response( { 'status': 0, 'msg': 'ok', 'results': user_data } ) def post(self, request, *args, **kwargs): # 新增一个资源 user_deser = UserSerializer(data=request.data) # result = user_deser.is_valid(raise_exception=True) # raise_exception值为True,当校验失败,直接返回drf自带的校验失败的错误信息 result = user_deser.is_valid() if result: new_user_obj = user_deser.save() return Response({ 'status': 0, 'msg': 'success', 'result': UserSerializer(new_user_obj).data }) else: return Response({ 'status': 1, 'msg': 'failed', 'results': user_deser.errors }) def put(self, request, *args, **kwargs): # 更新一个资源 pk = kwargs.get('pk') old_user_query = User.objects.filter(pk=pk, is_delete=False) user_deser = UserSerializer(instance=old_user_query, data=request.data) result = user_deser.is_valid() if result: new_user_query = user_deser.save() new_user_obj = new_user_query.first() return Response({ 'status': 0, 'msg': 'success', 'result': UserSerializer(new_user_obj).data }) else: return Response({ 'status': 1, 'msg': 'failed', 'results': user_deser.errors }) def delete(self, request, *args, **kwargs): # 删除一个资源 pk = kwargs.get('pk') try: delete_user_obj = User.objects.get(pk=pk, is_delete=False) delete_user_obj.is_delete = True # 完成删除信息的更新和保存 delete_user_obj.save() return Response() except: return Response({ 'status': 1, 'msg': '数据删除失败' })