本文目錄:
一、序列化類的增、删、改、查
二、局部和全局鈎子源碼流程
三、認證源碼分析執行流程
用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]