一、序列化类的增、删、改、查
用drf的序列化组件
-定义一个类继承class BookSerializer(serializers.Serializer):
-写字段,如果不指定source,字段名必须跟数据库字段名对应(source指定的值跟字段名不能重复)
-source还可以指定方法
-publish=serializers.SerializerMethodField()
def get_publish(self,obj):
obj.publish
#obj.authors.all()
- Serializer
-ModelSerializer
class Meta:
# 指定表模型
model = models.Book
# 序列化所有字段
fields = '__all__'
# 只想序列化title和id这俩字段
# fields = ['title', 'id']
# exclude 和fields 不要连用
# exclude = ['title']
depth=1
# 先创建一个序列化的类继承ModelSerializer
# ModelSerializer跟表模型绑定序列化 from app import models class BookSerializer(serializers.ModelSerializer): class Meta: # 指定表模型 model = models.Book # 序列化所有的字段 fields = '__all__' # 只想序列化title和id两个字段 # fields = ['title','id'] # exclude 和 fields不要连用 # excude = ['title] # depth深度,表示链表的深度 #不建议使用:下几层要取得参数不能控制,官方建议不要超过10,个人建议不超过3 # depth = 1 # publish = serializers.CharField(source='publish.name') # authors = serializers.SerializerMethodField() # def get_authors(self, obj): # author_list = obj.authors.all() # author_ser = AuthorSer(instance=author_list, many=True) # return author_ser.data #为书名增加自定义需求 title = serializers.CharField(max_length=6,min_length=3,error_messages={'max_length':'太长了'}) #也有局部钩子函数 def validate_title(self,value): from rest_framework import exceptions print(value) if value.startswith('tmd'): raise exceptions.ValidationError('不能以tmd开头') return value
#新增
from app.MySer import BookSerializer from django.views import View from rest_framework.views import APIView from rest_framework.response import Response from app import models class Books(APIView): # 新增方法 def post(self,request): response = {'status':100,'msg':'成功'} # book = request.data # 以往是提交字典,创建对象保存 # 新方法时通过序列化组件保存,必须继承自ModelSerializer # data注意是data book_ser = BookSerializer(data=request.data) # is_valid提交的字段通过验证 if book_ser.is_valid(): book_ser.save() response['book']=book_ser.data else: response['msg'] = book_ser.errors return Response(response)
#删除
class Book(APIView): # 删除方法 def delete(self,request,id): response = {'status': 100, 'msg': '删除成功'} book = models.Book.objects.filter(pk=id).delete() return Response(response)
# 修改
class Book(APIView): # 修改方法 def put(self,request,id): response={'status':100,'msg':'成功'} book = models.Book.objects.filter(pk=id).first() # 修改的话需要把book对象传过来,实例化ser对象出来 book_ser = BookSerializer(data=request.data,instance=book) # is_valid提交的字段校验通过 if book_ser.is_valid(): # save既可以修改,又可以更新 book_ser.save() response['book'] = book_ser.data else: response['msg'] = book_ser.errors return Response(response)
# 查询所有
class Books(APIView): # 查询方法多个 def get(self, request, *args, **kwargs): response = {'status': 100, 'msg': '成功'} book_list = models.Book.objects.all() # 第一个参数是要序列化的queryset对象,如果序列化多条,必须指定many=True # 问?什么情况下many=False,instance=单个对象的时候 book_ser = BookSerializer(book_list, many=True) print(book_ser.data) response['books'] = book_ser.data return Response(response)
# 查询单个
class Book(APIView): # 查询单个方法 def get(self,request, id): response = {'status':100,'msg':'成功'} book = models.Book.objects.filter(pk=id).first() book_ser = BookSerializer(book,many=False) response['book'] = book_ser.data return Response(response)
二、局部和全局钩子源码流程
#为书名增加自定义需求 title = serializers.CharField(max_length=6,min_length=3,error_messages={'max_length':'太长了'}) #也有局部钩子函数 def validate_title(self,value): from rest_framework import exceptions print(value) if value.startswith('tmd'): raise exceptions.ValidationError('不能以tmd开头') return value
三、认证源码分析执行流程
#Request对象的user方法 @property def user(self): the authentication classes provided to the request. if not hasattr(self, '_user'): with wrap_attributeerrors(): self._authenticate() return self._user def _authenticate(self): for authenticator in self.authenticators: try: user_auth_tuple = authenticator.authenticate(self) except exceptions.APIException: self._not_authenticated() raise #认证成功,可以返回一个元组,但必须是最后一个验证类才能返回 if user_auth_tuple is not None: self._authenticator = authenticator self.user, self.auth = user_auth_tuple return self._not_authenticated()
self.authenticators
def get_authenticators(self): return [auth() for auth in self.authentication_classes]