序列化基础
什么是序列化与反序列化
"""序列化:对象转换为字符串用于传输反序列化:字符串转换为对象用于使用"""
drf序列化与反序列化
"""序列化:Model类对象转换为字符串用于传输反序列化:字符串转换为Model类对象用于使用"""
Model类
创建数据库:终端
>: mysql -uroot -p密码>: create database 数据库名 charset=utf8
配置数据库:settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': '数据库名', 'USER': 'root', 'PASSWORD': '密码' }}
修改操作数据库的模块:项目init文件
import pymysqlpymysql.install_as_MySQLdb()
创建model类:models.py
from django.db import modelsclass 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) create_time = models.DateTimeField(auto_now_add=True, blank=True) class Meta: # 自定义创建的表名 db_table = 'o_user' # admin界面中显示的表面与表名复数形式 verbose_name = '用户' verbose_name_plural = verbose_name def __str__(self): return self.name
注册model类:admin.py
from django.contrib import adminfrom api.models import Useradmin.site.register(User)
数据库迁移:在项目目录下的终端
>: python3 manage.py makemigrations>: python3 manage.py migrate
注册超级用户:在项目目录下的终端
>: python3 manage.py createsuperuser
登陆admin页面添加数据:浏览器
http://localhost:8000/admin/
路由分发
项目urls.py
from django.conf.urls import url, includefrom django.contrib import adminurlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^api/', include('api.urls'))]
api应用urls.py
from django.conf.urls import urlurlpatterns = []
获取多资源 接口
from rest_framework import serializers# 为每一个Model类至少配一个Serializer类class UserSerializer(serializers.Serializer): # 序列化一个Model类对象,其实就是序列化该类的每一个属性 name = serializers.CharField() password = serializers.CharField() sex = serializers.IntegerField() create_time = serializers.DateTimeField()
视图类:views.py
from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom .models import Userfrom .serializers import UserSerializer# 对应路由:/users/# 功能:get获取所有 | post新增一个 | put修改一个 | delete删除一个class UsersAPIView(APIView): def get(self, request, *args, **kwargs): user_list = User.objects.all() # instance存放的是queryset对象,many需要设置为True user_data = UserSerializer(instance=user_list, many=True).data return Response( { 'status': 0, 'msg': 'ok', 'results': user_data } )
序列化字段操作(自定义字段)
序列化类修订:serializers.py
from rest_framework import serializers# 为每一个Model类至少配一个Serializer类class UserSerializer(serializers.Serializer): # 序列化一个Model类对象,其实就是序列化该类的每一个属性 # 注意1:Model类与Serializer类是通过属性名建立关联的 - 属性名必须依照 name = serializers.CharField() password = serializers.CharField() # sex = serializers.IntegerField() # 注意2:不需要通过给前台的数据,不需要提供该属性的序列化 # create_time = serializers.DateTimeField() # 注意3:serializers.SerializerMethodField()可以产生自定义序列化属性(不需要和Model类属性同步), # 但要为其绑定一个提供值的函数,函数名为 get_属性(self, obj) (obj为参与序列化的Model类对象) gender = serializers.SerializerMethodField() def get_gender(self, obj): # 该函数的返回值就作为对应自定义数据序列化后的值 return obj.get_sex_display()
新增单资源 接口
序列化类(反序列化类):serializers.py
from rest_framework import serializersfrom .models import Userclass UserDeserializer(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() # required=False该字段前台可以不用传(不参与校验) create_time = serializers.DateTimeField(required=False) # 完成ORM的操作 # def save(self): # 不能直接重写save,因为系统的save可以完成新增或修改 # # print(self.validated_data) # User.objects.create(**self.validated_data) # 为post接口提供新增Model类对象的功能 def create(self, validated_data): # 返回值:Model类要新增的对象 return User.objects.create(**validated_data)
视图类:views.py
from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom .models import Userfrom .serializers import UserSerializer# 对应路由:/users/# 功能:get获取所有 | post新增一个 | put修改一个 | delete删除一个class UsersAPIView(APIView): # 新增一个资源 def post(self, request, *args, **kwargs): user_deser = UserDeserializer(data=request.data) # raise_exception值为True,当校验失败,直接返回校验失败的错误信息 # result = user_deser.is_valid(raise_exception=True) 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 })
更新单资源 接口
序列化类(反序列化类):serializers.py
from rest_framework import serializersfrom .models import Userclass UserDeserializer(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() # required=False该字段前台可以不用传(不参与校验) create_time = serializers.DateTimeField(required=False) # 完成ORM的操作 # def save(self): # 不能直接重写save,因为系统的save可以完成新增或修改 # # print(self.validated_data) # User.objects.create(**self.validated_data) # 为post接口提供新增Model类对象的功能 def create(self, validated_data): # 返回值:Model类要新增的对象 return User.objects.create(**validated_data) # 为put接口提供更新Model类对象的功能 def update(self, instance, validated_data): # 操作model对象 # instance.name = validated_data.get('name') # instance.password = validated_data.get('password') # instance.sex = validated_data.get('sex') # instance.save() # 操作queryset对象 instance.update(**validated_data) return instance
视图类:views.py
from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom .models import Userfrom .serializers import UserSerializer# 对应路由:/users/# 功能:get获取所有 | post新增一个 | put修改一个 | delete删除一个class UsersAPIView(APIView): # 更新一个资源 def put(self, request, *args, **kwargs): # 要更新的资源的主键 pk = kwargs.get('pk') # 操作更新时可以选择操作 queryset对象 或 model对象 # 操作model对象 # old_user_obj = User.objects.get(pk=pk) # user_deser = UserDeserializer(instance=old_user_obj, data=request.data) # 操作queryset对象 old_user_query = User.objects.filter(pk=pk) user_deser = UserDeserializer(instance=old_user_query, data=request.data) # raise_exception值为True,当校验失败,直接返回校验失败的错误信息 # result = user_deser.is_valid(raise_exception=True) result = user_deser.is_valid() if result: # new_user_obj = user_deser.save() # 操作model对象 new_user_query = user_deser.save() # 操作queryset对象 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 })
删除单资源 接口
重构Model新增字段:models.py
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) create_time = models.DateTimeField(auto_now_add=True, blank=True) # 新增:数据删除不是从数据库删除记录,而是修改记录状态,标示为已删除即可 is_delete = models.BooleanField(default=False) class Meta: # 自定义创建的表名 db_table = 'o_user' # admin界面中显示的表面与表名复数形式 verbose_name = '用户' verbose_name_plural = verbose_name def __str__(self): return self.name
数据库迁移:在项目目录下的终端
>: python3 manage.py makemigrations>: python3 manage.py migrate
视图类接口:views.py
from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom .models import Userfrom .serializers import UserSerializer# 对应路由:/users/# 功能:get获取所有 | post新增一个 | put修改一个 | delete删除一个class UsersAPIView(APIView): # 删除一个资源 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': '数据删除失败' })
获取单资源 接口
序列化类:serializers.py
from rest_framework import serializers# 为每一个Model类至少配一个Serializer类class UserSerializer(serializers.Serializer): # 序列化一个Model类对象,其实就是序列化该类的每一个属性 name = serializers.CharField() password = serializers.CharField() sex = serializers.IntegerField() create_time = serializers.DateTimeField()
视图类:views.py
from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom .models import Userfrom .serializers import UserSerializer# 对应路由:/users/# 功能:get获取所有 | post新增一个 | put修改一个 | delete删除一个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) # 如果只操作一个对象,many参数需要为False(默认值) # user_obj = User.objects.filter(is_delete=False, pk=pk).first() # user_data = UserSerializer(instance=user_obj, many=False).data user_data = UserSerializer(instance=user_query, many=True).data return Response( { 'status': 0, 'msg': 'ok', 'results': user_data } )
序列化基础:重点内容
模型类:models.py
from django.db import models# Create your models here.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) create_time = models.DateTimeField(auto_now_add=True, blank=True) # 数据删除不是从数据库删除记录,而是修改记录状态,标示为已删除即可 is_delete = models.BooleanField(default=False) class Meta: # 自定义创建的表名 db_table = 'o_user' # admin界面中显示的表面与表名复数形式 verbose_name = '用户' verbose_name_plural = verbose_name def __str__(self): return self.name
序列化类:
from rest_framework import serializersfrom .models import Userclass 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': '密码太短' }) # 只有反序列化使用 - 用 write_only=True 标示只参与反序列化 sex = serializers.IntegerField(write_only=True) # 只有序列化使用 - 自定义字段 - 用 read_only=True 标示只参与序列化 gender = serializers.SerializerMethodField(read_only=True) def get_gender(self, obj): return obj.get_sex_display() # 序列化与反序列化都不使用 - 1)注释 | 2)required=False, write_only=True create_time = serializers.DateTimeField(required=False, write_only=True) # 为全局校验钩子新增校验字段 re_password = serializers.CharField(label='确认密码', max_length=64, min_length=3, write_only=True, error_messages={ 'max_length': '确认密码太长', 'min_length': '确认密码太短' }) # 反序列化两大方法重写 - 新增create | 更新update # 为post接口提供新增Model类对象的功能 def create(self, validated_data): # 返回值:Model类要新增的对象 return User.objects.create(**validated_data) # 为put接口提供更新Model类对象的功能 def update(self, instance, validated_data): instance.update(**validated_data) # 返回更新后的instance return 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 APIViewfrom rest_framework.response import Responsefrom .models import Userfrom .serializers import UserSerializer# 对应路由:/users/ | /users/pk/# 功能:get获取所有 | post新增一个 | put修改一个 | delete删除一个 | get获取一个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 return Response( { 'status': 0, 'msg': 'ok', 'results': user_data } ) # 新增一个资源 def post(self, request, *args, **kwargs): user_deser = UserSerializer(data=request.data) # raise_exception值为True,当校验失败,直接返回校验失败的错误信息 # result = user_deser.is_valid(raise_exception=True) 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) # 没有数据 if not old_user_query: return Response({ 'status': 1, 'msg': 'update failed', }) 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': '数据删除失败' })