02.Django REST framework - 序列化组件
序列化器-Serializer
什么是rest_framework序列化?
在写前后端不分离的项目时:
我们有form组件帮我们去做数据校验
我们有模板语法,从数据库取出的queryset对象不需要人为去转格式
当我们写前后端分离项目的时:
我们需要自己去做数据校验
我们需要手动去转数据格式,因为跨平台数据传输都用json字符串,不能直接jsonqueryset对象
序列化器的作用
1 序列化:把python中的对象转成json格式字符串 序列化器会把模型对象转换成字典,经过response以后变成json字符串 2 反序列化:把json格式字符串转成python中的对象 把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型 3 注意:drf的序列化组件(序列化器) 把对象(Book,queryset对象)转成字典 因为有字典,直接丢到Response中就可以了
序列化,反序列化 -对象----》json -json---》对象 序列化器 -定义一个类,继承Serializer -在类内些字段(常用字段,和非常用字段)(字段参数) -在视图类中,实例化得到一个序列化类的对象,传入要序列化的数据 -对象.data---》就是字典 -source
序列化器的基本使用
from rest_framework.serializers import Serializer,ModelSerializer from rest_framework import serializers
Serializer是rest_framework原生的序列化组件 ModelSerializer是rest_framework在原生的序列化组件的基础上封装了一层的序列化组件
用法:1、在用我们的rest_framework序列化组件的时候,我们的视图层都必须写视图类,不能再写视图函数
2、我们需要针对每一张模型表写一个类来继承Serailizer或者ModelSerailizer类,
注:当我们在视图类里需要对数据进行序列化或者反序列化的时候,在自己定义的类传入需要序列化的数据实例化,
调用.data即可拿到序列化或者校验后的数据了
Django REST framework中的Serializer使用类来定义,须继承自rest_framework.serializers.Serializer
1 写一个序列化的类,继承Serializer class BookSerializer(serializers.Serializer): # 在这里写要序列化的字段 # 序列化字段类(有很多,常用的就几个,等同于models中的字段类) # 字段类,有很多字段参数() name = serializers.CharField() price = serializers.IntegerField() # publish = serializers.CharField() 2 在类中写要序列化的字段(常用字段,和非常用字段)(字段参数) name = serializers.CharField() price = serializers.IntegerField() 3 在视图类中使用(实例化得到一个序列化类的对象,传入要序列化的数据) class BookView(APIView): def get(self, request): book_list = models.Book.objects.all() # instance=None, 要序列化的数据 # data=empty ,要反序列化的数据(目前data先不用) # many=True 如果序列化多条,一定要写many=True book_ser = BookSerializer(instance=book_list, many=True) # book_ser.data就是序列化后的数据 return Response(book_ser.data) 4 得到序列化后的数据,返回(对象.data---》就是字典) book_ser.data 5 字段参数,source,指定要序列化表中的哪个字段 ##########具体操作步骤见下方详细操作#########
路由层 urls.py
from django.urls import path from app import views urlpatterns = [ path('admin/', admin.site.urls), # 获取所有的书籍信息 path('books_new/', views.BookView.as_view()), # 对某本书进行操作 path('books_new/<int:id>/', views.BookViewId.as_view()), ]
模型层 models.py
from django.db import models class Book(models.Model): name = models.CharField(max_length=32, verbose_name='书名') publish = models.CharField(max_length=32, verbose_name='出版社') price = models.IntegerField(verbose_name='价格')
序列化器层 serializer.py
from rest_framework import serializers from app import models # 新建序列化类,继承Serializer class BookSerializer(serializers.Serializer): # 类中定义和模型表一一对应的字段,在这里写要序列化的字段 # 序列化字段类(有很多,常用的就几个,等同于models中的字段类) # 字段类,有很多字段参数() name = serializers.CharField() price = serializers.IntegerField() publish = serializers.CharField()
视图层 views.py
# 获取所有书籍信息 class BookView(APIView): def get(self, request): book_list = models.Book.objects.all() book_ser = BookSerializer(instance=book_list, many=True) # book_ser.data就是序列化后的数据 return Response(book_ser.data) """ instance=None, 要序列化的数据 data=empty ,要反序列化的数据(目前data先不用) many=True 如果序列化多条,一定要写many=True """ # 对某一本书进行操作 class BookViewId(APIView): # 对某一个进行操作需要带上id def get(self, request, id): book = models.Book.objects.all().filter(pk=id).first() book_ser = BookSerializer(instance=book) return Response(book_ser.data)
source
1 指定要序列化的字段(数据表中字段) publish = serializers.CharField(source='publish.city') # 拿到出版社所在的城市 2 用的最多:只有一个字段(也可以跨表)
SerializerMethodField
用的最多:跨表查((来定制返回的字段)要么是列表,要么是字典) publish=serializers.SerializerMethodField() def get_publish(self,obj): print(obj) # return {'name':'sss','city':'sss'} return {'name':obj.publish.name,'city':obj.publish.city,'email': obj.publish.email}
# models.py 表模型中写的 class Book(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) publish_date = models.DateField() publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE) authors=models.ManyToManyField(to='Author') def __str__(self): return self.name # def publish_name(self): # return self.publish.name def publish_name(self): return {'name':self.publish.name,'city':self.publish.city} @property def author_list(self): # 列表推导式 return [{'name':author.name,'age':author.age,'id':author.nid} for author in self.authors.all()]
# serializers.py 序列化类中 class BookSerializer(serializers.Serializer): name = serializers.CharField() price = serializers.IntegerField() publish_name = serializers.DictField() author_list = serializers.ListField()
注意:serializer不是只能为数据库模型类定义,也可以为非数据库模型类的数据定义。serializer是独立于数据库之外的存在。
序列化类常用字段类型及属性
字段参数针对性分类
# 针对charfield max_length 最大长度 min_lenght 最小长度 allow_blank 是否允许为空 # 针对interfield max_value 最小值 min_value 最大值 # 通用的,大家都有 # 这两个最重要 read_only 表明该字段仅用于序列化输出,默认False(序列化) write_only 表明该字段仅用于反序列化输入,默认False(反序列化) required 表明该字段在反序列化时必须输入,默认True default 反序列化时使用的默认值 allow_null 表明该字段是否允许传入None,默认False error_messages 包含错误编号与错误信息的字典 validators 该字段使用的验证器(了解)
反序列化,局部钩子,全局钩子
使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象。
在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False。
验证失败,可以通过序列化器对象的errors属性获取错误信息,返回字典,包含了字段和字段的错误。如果是非字段错误,可以通过修改REST framework配置中的NON_FIELD_ERRORS_KEY来控制错误字典中的键名。
验证成功,可以通过序列化器对象的validated_data属性获取数据。
在定义序列化器时,指明每个字段的序列化类型和选项参数,本身就是一种验证行为。
1 如果要反序列化,继承了Serializer,必须重写create方法 2 使用 # 视图类 def post(self, request): publish_ser = serializer.PublishSerializer(data=request.data) if publish_ser.is_valid(): # 校验数据 # 直接保存,保存到哪个表里?需要重写save publish_ser.save() return Response(publish_ser.data) else: print(publish_ser.errors) return Response('数据有问题啊') # 序列化类 def create(self, validated_data): # 校验过后的数据 res = models.Publish.objects.create(**validated_data) return res """ 父类的save内部调用了create,所以我们重写create return res 给了self.instance以后,instance就有值了 publish_ser.data,instance就有值调用data就能拿到序列化后的数据 is_valid()方法还可以在验证失败时抛出异常serializers.ValidationError,可以通过传递raise_exception=True参数开启, REST framework接收到此异常,会向前端返回HTTP 400 Bad Request响应。 """
# validate_字段名 def validate_name(self, data): # data就是当前字段的值 if data.startswith('sb'): raise ValidationError('不能以sb开头') else: return data # 在序列化器中需要同时对多个字段进行比较验证时,可以定义validate方法来验证 def validate(self, attrs): if attrs.get('name') == attrs.get('city'): raise ValidationError('city和名字不能一样') else: return attrs
如果我们想要使用序列化器对应的是Django的模型类,DRF为我们提供了ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类。
ModelSerializer与常规的Serializer相同,但提供了:
-
基于模型类自动生成一系列字段
-
基于模型类自动为Serializer生成validators,比如unique_together
-
包含默认的create()和update()的实现
视图类 views.py
class BookView(APIView): def get(self,request): qs=models.Book.objects.all() ser=serializer.BookModelSerializer(instance=qs,many=True) return Response(ser.data) def post(self,request): ser = serializer.BookModelSerializer(data=request.data) if ser.is_valid(): ser.save() return Response(ser.data) else: return Response(ser.errors) class BookDetailView(APIView): def get(self,request,id): book = models.Book.objects.filter(pk=id).first() ser = serializer.BookModelSerializer(instance=book) return Response(ser.data) def put(self,request,id): book = models.Book.objects.filter(pk=id).first() ser = serializer.BookModelSerializer(instance=book,data=request.data) if ser.is_valid(): ser.save() return Response(ser.data) else: return Response(ser.errors) def delete(self,request,id): res = models.Book.objects.filter(pk=id).delete() if res[0] > 0: return Response('') else: return Response('要删的不存在')
""" ModelSerializer 使用步骤: 1、新建序列化类,继承ModelSerializer 2、类中定义和模型表一一对应的字段,这里可以定义class Meta() 然后指定模型表model和 映射字段fields,比Serializer更简洁 -其中类中的名字可以改变,需要在serializers.CharField()的括号中指定source=某个字段,建议映射关系 -外键关系的字段可以用serializers.SerializerMethodField(),需要在下方固定写 get_字段名 的方法, 这里可以写具体逻辑,最终返回结果就是该字段的结果 3、当新增数据的时候不需要重写父类的create方法,这里ModelSerializer做了封装 4、当修改数据的时候不需要重写父类的update方法,这里ModelSerializer做了封装 5、当完成这些配置后就可以在视图类中实例化调用了,序列化的时候序列化,反序列化的时候校验 """ from rest_framework import serializers from app import models class BookModelSerializer(serializers.ModelSerializer): class Meta: model = models.Book # model 指明参照哪个模型类 fields = '__all__' # fields 指明为模型类的哪些字段生成,__all__表名包含所有字段 # 给字段类加属性 extra_kwargs = { 'publish': {'required': True, 'write_only': True}, 'authors': {'required': True, 'write_only': True}, } publish_detail = PublishSerializer(source='publish',read_only=True) author_list=serializers.ListField(read_only=True) # 字段自己的校验,全局钩子,局部钩子 """ 使用fields来明确字段,__all__表名包含所有字段,也可以写明具体哪些字段,如 使用exclude可以明确排除掉哪些字段 使用extra_kwargs参数为ModelSerializer添加或修改原有的选项参数 """
from django.db import models class Book(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32, verbose_name='书名') price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='价格') publish_date = models.DateField(verbose_name='出版时间') publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE) authors=models.ManyToManyField(to='Author') class Meta: verbose_name_plural = '书籍表' def __str__(self): return self.name # 表模型写方法,展示更多字段 # def publish_name(self): # return self.publish.name # def publish_name(self): # return {'name':self.publish.name,'city':self.publish.city} # # @property # def author_list(self): # return [{'name':author.name,'age':author.age,'id':author.nid} for author in self.authors.all()] class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32, verbose_name='名字') age = models.IntegerField(verbose_name='年龄') author_detail = models.OneToOneField(to='AuthorDetail',to_field='nid',unique=True,on_delete=models.CASCADE)class Meta: verbose_name_plural = '作者表' def __str__(self): return self.name class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) telephone = models.BigIntegerField(verbose_name='电话') birthday = models.DateField(verbose_name='生日') addr = models.CharField(max_length=64, verbose_name='地址') class Meta: verbose_name_plural = '作者详情表' class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32, verbose_name='社名') city = models.CharField(max_length=32, verbose_name='地址') email = models.EmailField(verbose_name='邮箱') class Meta: verbose_name_plural = '出版社表' def __str__(self): return self.name
urlpatterns = [ path('books/',views.BookView.as_view()), path('books/<int:id>/',views.BookDetailView.as_view()), ]
序列化高级用法
ModelSerializer用的基本就是下面这个方法 class BookModelSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = "__all__" """ 如果想让字段更丰富些,可以采用任意一种方法实现(方法有很多种) 第一种方法:source publish = serializers.CharField(source='publish.city') 第二种方法:SerializerMethodField publish=serializers.SerializerMethodField() def get_publish(self,obj): return {'name':obj.publish.name,'city':obj.publish.city,'email': obj.publish.email} 第三种方法:在表模型写方法 def publish_name(self): return {'name':self.publish.name,'city':self.publish.city} @property def author_list(self): return [{'name':author.name,'age':author.age,'id':author.nid} for author in self.authors.all()] 第四种方法:子序列化 publish = Publishserializer() """
如果上方的说明还不清晰,可粘贴到项目中运行。django版本2.2.2
仅演示方法,功能未完善不要在意

from rest_framework.serializers import ModelSerializer from rest_framework import serializers from app01 import models from rest_framework.exceptions import ValidationError class BookModelSerializer(ModelSerializer): class Meta(): model = models.Book fields = "__all__" # 需要跟表模型中写的方法对应 publish_name = serializers.DictField() author_list = serializers.ListField() class AuthorDatailModelserializer(ModelSerializer): class Meta(): model = models.AuthorDetail fields = "__all__" class AuthorModelSerializer(ModelSerializer): class Meta(): model = models.Author fields = "__all__" # 第一种方法:source,只能选择一个字段 # author_detail = serializers.CharField(source='author_detail.birthday') # 第二种方法:SerializerMethodField,可多选 # author_detail = serializers.SerializerMethodField() # def get_author_detail(self, obj): # return {'p': obj.author_detail.telephone, 'b': obj.author_detail.birthday} # 第三种方法:在表模型中写方法,需跟模型表models对应 # author_detail = serializers.DictField(source='author_detail_name') # 第四种方法:子序列化(Publishserializer需要在当前类上方提前定义好) # author_detail = AuthorDatailModelserializer() # def validate_name(self, data): # if data.startswith('sb'): # raise ValidationError('作者名不能有敏感词汇') class PublishModelSerializer(ModelSerializer): class Meta(): model = models.Publish fields = "__all__" # def validate_name(self, data): # if data.startswith('sb'): # raise ValidationError('出版社名不能有敏感词汇') 序列化类 serializer.py

from django.db import models class Book(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32, verbose_name='书名') price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='价格') publish_date = models.DateField(verbose_name='出版时间') publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE) authors=models.ManyToManyField(to='Author') class Meta: verbose_name_plural = '书籍表' def __str__(self): return self.name # 表模型写方法,展示更多字段 def publish_name(self): return {'name':self.publish.name,'city':self.publish.city} @property def author_list(self): return [{'name':author.name,'age':author.age,'id':author.nid} for author in self.authors.all()] class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32, verbose_name='名字') age = models.IntegerField(verbose_name='年龄') author_detail = models.OneToOneField(to='AuthorDetail',to_field='nid',unique=True,on_delete=models.CASCADE) # 表模型写方法,展示更多字段 def author_detail_name(self): return {'telephone':self.author_detail.telephone, 'birthday':self.author_detail.birthday, 'addr':self.author_detail.addr} class Meta: verbose_name_plural = '作者表' def __str__(self): return self.name class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) telephone = models.BigIntegerField(verbose_name='电话') birthday = models.DateField(verbose_name='生日') addr = models.CharField(max_length=64, verbose_name='地址') class Meta: verbose_name_plural = '作者详情表' class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32, verbose_name='社名') city = models.CharField(max_length=32, verbose_name='地址') email = models.EmailField(verbose_name='邮箱') class Meta: verbose_name_plural = '出版社表' def __str__(self): return self.name 模型层 models.py

from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), # 查询所有书籍,增加书籍 path('book/', views.BookView.as_view()), # 查询,修改,删除单本书籍 path('book/<int:pk>/', views.BookDetailView.as_view()), # 查询所有作者,增加作者 path('author/', views.AuthorView.as_view()), # 查询,修改,删除单个作者 path('author/<int:pk>/', views.AuthorDetailView.as_view()), ] 路由层 urls.py

from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from app01 import serializer from app01 import models # 查询所有书籍,增加书籍 class BookView(APIView): def get(self, request): books = models.Book.objects.all() ser = serializer.BookModelSerializer(instance=books, many=True) return Response(ser.data) def post(self, request): ser = serializer.BookModelSerializer(data=request.data) if ser.is_valid(): # 直接保存,保存到哪个表里?需要重写save ser.save() return Response(ser.data) return Response(ser.errors) # 查询,修改,删除单本书籍 class BookDetailView(APIView): def get(self, request, *args, **kwargs): book = models.Book.objects.filter(pk=kwargs.get('pk')).first() ser = serializer.BookModelSerializer(instance=book) print(ser.instance) return Response(ser.data) def put(self, request, *args, **kwargs): book = models.Book.objects.filter(pk=kwargs.get('pk')).first() ser = serializer.BookModelSerializer(instance=book, data=request.data) if ser.is_valid(): ser.save() return Response(ser.data) else: return Response('数据校验有误') def delete(self, request, *args, **kwargs): book = models.Book.objects.filter(pk=kwargs.get('pk')).delete() print(book) if book[0] > 0: return Response('') else: return Response('要删的不存在') # 查看所有作者,增加作者 class AuthorView(APIView): def get(self,request): author = models.Author.objects.all() ser = serializer.AuthorModelSerializer(instance=author,many=True) return Response(ser.data) def post(self,request): ser = serializer.AuthorModelSerializer(data=request.data) if ser.is_valid(): ser.save() return Response(ser.data) return Response(ser.errors) # 查看单个作者。。。修改删除功能未完善 class AuthorDetailView(APIView): def get(self,request, *args, **kwargs): author = models.Author.objects.filter(pk=kwargs.get('pk')).first() ser = serializer.AuthorModelSerializer(instance=author) return Response(ser.data) 视图层 views.py
1 序列化类实例化的时候,传了many,序列化多条,不传,就序列化单条 # many=True,实例化得到的对象是ListSerializer ser=serializer.BookModelSerializer(instance=qs,many=True) print(type(ser)) # rest_framework.serializers.ListSerializer # 列表中套了很多BookModelSerializer # many=False,实例化得到的对象是BookModelSerializer ser=serializer.BookModelSerializer(instance=book) print(type(ser)) # app01.serializer.BookModelSerializer 类实例化:在执行__init__之前,先执行了__new__生成一个空对象(决定了是哪个类的对象) 在__new__中进行判断,如果many=True,就返回ListSerializer的对象
入口 is_valid() 判断_validated_data如果没有 执行了 self.run_validation(self.initial_data) 目前在BaseSerializer,如果按住ctrl点击,会直接进到它父类的run_validation,进到Field,不是真正执行的方法 我们需要从头找,实际上是Serializer类的run_validation def run_validation(self, data=empty): value = self.to_internal_value(data)#字段自己的校验和局部钩子 try: self.run_validators(value) value = self.validate(value) # 全局钩子 assert value is not None, except (ValidationError, DjangoValidationError) as exc: raise ValidationError(detail=as_serializer_error(exc)) return value 局部钩子是在 to_internal_value执行的 def to_internal_value(self, data): for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) if validate_method is not None: validated_value = validate_method(validated_value)
序列化对象.data方法--调用父类data方法---调用对象自己的 to_representation(自定义的序列化类无此方法,去父类找) Serializer类里有to_representation方法 for循环执行attribute = field.get_attribute(instance) 再去Field类里去找get_attribute方法,self.source_attrs就是被切分的source 然后执行get_attribute方法,source_attrs 当参数传过去,判断是方法就加括号执行,是属性就把值取出来
REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST framework提供的扩展了HttpRequest类的Request类的对象。
REST framework 提供了Parser解析器,在接收到请求后会自动根据Content-Type指明的请求数据类型(如JSON、表单等)将请求数据进行parse解析,解析为类字典[QueryDict]对象保存到Request对象中。
Request对象的数据是自动根据前端发送数据的格式进行解析之后的结果。
无论前端发送的哪种格式的数据,我们都可以以统一的方式读取数据。
常用属性
1).data request.data 返回解析之后的请求体数据。类似于Django中标准的request.POST和 request.FILES属性,但提供如下特性: 包含了解析之后的文件和非文件数据 包含了对POST、PUT、PATCH请求方式解析后的数据 利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据 2).query_params request.query_params与Django标准的request.GET相同,只是更换了更正确的名称而已
解析模块配置
from rest_framework.settings import APISettings
# 自定义drf配置
REST_FRAMEWORK = {
# 解析模块
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser', # json数据类型
'rest_framework.parsers.FormParser', # urlencoded数据类型
'rest_framework.parsers.MultiPartParser' # from-data数据类型
],
# 渲染模块
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer', # 数据渲染
'rest_framework.renderers.BrowsableAPIRenderer', # 浏览器渲染
],
}
渲染模块配置
浏览器渲染打开
别人知道你后台用什么写的,好攻击你
浏览器渲染关闭
效果:数据正常渲染,浏览器只有数据。别人不知道你后台数据怎么写的,不容易攻击你
结论
当项目没上线的时候:一般浏览器渲染打开
当项目上线:为了安全一般把浏览器渲染关闭
REST framework提供了一个响应类Response
,使用该类构造响应对象时,响应的具体数据内容会被转换(render渲染)成符合前端需求的类型。
REST framework提供了Renderer
渲染器,用来根据请求头中的Accept
(接收数据类型声明)来自动转换响应数据到对应格式。如果前端请求中未进行Accept声明,则会采用默认方式处理响应数据,我们可以通过配置来修改默认响应格式。
可以在rest_framework.settings查找所有的drf默认配置项
REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( # 默认响应渲染类 'rest_framework.renderers.JSONRenderer', # json渲染器 'rest_framework.renderers.BrowsableAPIRenderer', # 浏览API渲染器 ) }
data
数据不要是render处理之后的数据,只需传递python的内建类型数据即可,REST framework会使用renderer
渲染器处理data
。
data
不能是复杂结构的数据,如Django的模型类对象,对于这样的数据我们可以使用Serializer
序列化器序列化处理后(转为了Python字典类型)再传递给data
参数。
参数说明:
#一直会用 data: 为响应准备的序列化处理后的数据(字典) #偶尔会用 headers: 用于存放响应头信息的字典; status: 状态码,默认200;(http请求的状态码) # 基本不用 template_name: 模板名称,如果使用HTMLRenderer 时需指明; content_type: 响应数据的Content-Type,通常此参数无需传递,REST framework会根据前端所需类型数据来设置该参数。
1).data 传给response对象的序列化后,但尚未render处理的数据 2).status_code 状态码的数字 3).content 经过render处理后的响应数据
1)信息告知 - 1xx HTTP_100_CONTINUE = 100 HTTP_101_SWITCHING_PROTOCOLS = 101 2)成功 - 2xx HTTP_200_OK = 200 HTTP_201_CREATED = 201 HTTP_202_ACCEPTED = 202 HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203 HTTP_204_NO_CONTENT = 204 HTTP_205_RESET_CONTENT = 205 HTTP_206_PARTIAL_CONTENT = 206 HTTP_207_MULTI_STATUS = 207 HTTP_208_ALREADY_REPORTED = 208 HTTP_226_IM_USED = 226 3)重定向 - 3xx HTTP_300_MULTIPLE_CHOICES = 300 HTTP_301_MOVED_PERMANENTLY = 301 HTTP_302_FOUND = 302 HTTP_303_SEE_OTHER = 303 HTTP_304_NOT_MODIFIED = 304 HTTP_305_USE_PROXY = 305 HTTP_306_RESERVED = 306 HTTP_307_TEMPORARY_REDIRECT = 307 HTTP_308_PERMANENT_REDIRECT = 308 4)客户端错误 - 4xx HTTP_400_BAD_REQUEST = 400 HTTP_401_UNAUTHORIZED = 401 HTTP_402_PAYMENT_REQUIRED = 402 HTTP_403_FORBIDDEN = 403 HTTP_404_NOT_FOUND = 404 HTTP_405_METHOD_NOT_ALLOWED = 405 HTTP_406_NOT_ACCEPTABLE = 406 HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407 HTTP_408_REQUEST_TIMEOUT = 408 HTTP_409_CONFLICT = 409 HTTP_410_GONE = 410 HTTP_411_LENGTH_REQUIRED = 411 HTTP_412_PRECONDITION_FAILED = 412 HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413 HTTP_414_REQUEST_URI_TOO_LONG = 414 HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415 HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416 HTTP_417_EXPECTATION_FAILED = 417 HTTP_418_IM_A_TEAPOT = 418 HTTP_422_UNPROCESSABLE_ENTITY = 422 HTTP_423_LOCKED = 423 HTTP_424_FAILED_DEPENDENCY = 424 HTTP_426_UPGRADE_REQUIRED = 426 HTTP_428_PRECONDITION_REQUIRED = 428 HTTP_429_TOO_MANY_REQUESTS = 429 HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431 HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451 5)服务器错误 - 5xx HTTP_500_INTERNAL_SERVER_ERROR = 500 HTTP_501_NOT_IMPLEMENTED = 501 HTTP_502_BAD_GATEWAY = 502 HTTP_503_SERVICE_UNAVAILABLE = 503 HTTP_504_GATEWAY_TIMEOUT = 504 HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505 HTTP_506_VARIANT_ALSO_NEGOTIATES = 506 HTTP_507_INSUFFICIENT_STORAGE = 507 HTTP_508_LOOP_DETECTED = 508 HTTP_509_BANDWIDTH_LIMIT_EXCEEDED = 509 HTTP_510_NOT_EXTENDED = 510 HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511 #drf推荐的写法 return Response(ser.data,status.HTTP_200_OK)
drf 整体内容概述
0 drf是django的一个app -序列化器 -Request -Response -版本控制 -认证,频率,权限 -过滤,排序,分页 -视图相关 -自动生成接口文档(coreapi,swagger) -jwt做认证(第三方) -xadmin---》对admin的美化(bootstrap+jq,1.x版本),simple-ui -RBAC:基于角色的访问控制(公司内部项目) 1 序列化器 1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 2. 反序列化,把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型 3. 反序列化,完成数据校验功能 2 Serializer -序列化 -实例化序列化对象,many参数作用 -source -SerializerMethodField -模型表中写方法 -反序列化 -ser=BookSerializer(data=request.data) -数据校验:ser.is_valid() -存数据:手动存,重写BookSerializer的create方法,update方法 -ser.save() 如果是新增,会调用create,如果是修改,会调用update -ser.data 如果有instance对象,就是对instance做序列化 -全局,局部钩子,字段参数
3 ModelSerializer -class Meta: model=Book fields=‘__all__’ extra_kwargs -重写某个字段:跟之前学的又一样了 -子序列化
4 常用非常用字段
5 字段参数
6 如果第三张表是手动建的,authors是存不进去的 { name:ddd price:10 publish:1 authors:[1,2] } 7 请求对象的属性 8 响应对象 -data:响应数据 -status:响应状态码 -header:响应头 -content_type:响应类型 9 加入serializer后整个后端逻辑