1.模塊與包
# 模塊與包
模塊:一個py文件 被別的py文件導入使用,這個py文件稱之為模塊,運行的這個py文件稱之為腳本文件
包:一個文件夾下有__init__.py
# 模塊與包的導入問題
'''
1.導入模塊有相對導入和絕對導入,絕對導入的路徑是從環(huán)境變量開始的
2.導入任何模塊,如果使用絕對導入,都是從環(huán)境變量開始導起
3.腳本文件執(zhí)行的路徑,會自動加入環(huán)境變量
4.相對導入的話,是從當前py文件開始計算的
5.以腳本運行的文件,不能使用相對導入,只能用絕對導入
'''
2.反序列化校驗源碼分析(了解)
# 序列化類的校驗功能
局部鉤子:必須 validate_字段名
全局鉤子:validate
# 入口
ser.is_valid 才做的校驗---》入口
先從自己寫的BookSerializer類中找is_valid方法----》再到繼承的父類Serializer中找---》再到它的父類BaseSerializer中找----》is_valid---》還繼承了Field
'''BookSerializer類中的is_valid方法'''
def is_valid(self, *, raise_exception=False):
# self中沒有_validated_data,只有執(zhí)行完后,才有(校驗過后的數(shù)據(jù))
if not hasattr(self, '_validated_data'):
try:
# 核心---》這一句
# 想看它的源代碼,按住ctrl+鼠標點擊是不對的---》只能找當前類的父類,要從根上開始找
self._validated_data = self.run_validation(self.initial_data)
except ValidationError as exc:
self._validated_data = {}
self._errors = exc.detail
else:
self._errors = {}
if self._errors and raise_exception:
raise ValidationError(self.errors)
return not bool(self._errors)
"""
self.run_validation(self.initial_data)
在Serializer中有run_validation這個方法先執(zhí)行這個
"""
def run_validation(self, data=empty):
# 局部鉤子
value = self.to_internal_value(data)
try:
# 全局鉤子
value = self.validate(value) # BookSerializer只要寫了,優(yōu)先執(zhí)行它的
except (ValidationError, DjangoValidationError) as exc:
raise ValidationError(detail=as_serializer_error(exc))
return value
"""
局部鉤子
self.to_internal_value(data)---》Serializer類的方法
"""
def to_internal_value(self, data):
for field in fields: #序列化類中寫的一個個的字段類的對象列表
# 一個field是name對象,field.field_name字符串 name
# self是誰的對象:序列化類的對象,BookSerializer的對象 validate_name
validate_method = getattr(self, 'validate_' + field.field_name, None)
try:
# 字段自己的校驗規(guī)則
validated_value = field.run_validation(primitive_value)
if validate_method is not None:
# 局部鉤子
validated_value = validate_method(validated_value)
except ValidationError as exc:
errors[field.field_name] = exc.detail
except DjangoValidationError as exc:
errors[field.field_name] = get_error_detail(exc)
except SkipField:
pass
else:
set_value(ret, field.source_attrs, validated_value)
if errors:
raise ValidationError(errors)
return ret
# 總結
ser.is_valid--->走局部鉤子的代碼---》是通過反射獲取BookSerializer中寫的局部鉤子函數(shù),如果寫了,就會執(zhí)行---》走全局鉤子代碼---》self.validate(value)---》只要序列化類中寫了,優(yōu)先走自己的
3.斷言
assert hasattr(self, 'initial_data'), (
'Cannot call `.is_valid()` as no `data=` keyword argument was '
'passed when instantiating the serializer instance.'
)
# 斷言某個東西是我認為的,如果不是就拋異常
# 等同于if判斷+拋異常
def add(a,b):
return a + b
res = add(8,9)
# assert res == 16,Exception('不等于16')
if not res == 16:
raise Exception('不等于16')
print('隨便')
4.drf之請求
# 視圖類:APIView
# 序列化組件:Serializer,ModelSerializer
# drf:Request類的對象
4.1Request類對象的分析
1.data
request.data 返回解析之后的請求體數(shù)據(jù)。類似于Django中標準的request.POST和request.FILES屬性,但提供如下特性:
包含了解析之后的文件和非文件數(shù)據(jù)
包含了對POST、PUT、PATCH請求方式解析后的數(shù)據(jù)
利用了REST framework的parsers解析器,不僅支持表單類型數(shù)據(jù),也支持JSON數(shù)據(jù)
2..query_params
request.query_params等同于request.GET
3.其他的屬性用法跟之前一樣
4.2請求能夠接受的編碼格式
# urlencoded
# form-data
# json
三種都支持
可以限制只能接受某種或者某幾種編碼格式
# 限制方式一:在視圖類上寫--》只是局部視圖類有效
# 總共有三個:JSONParser,FormParser, MultiPartParser
class BookView(APIView):
parser_classes = [JSONParser, FormParser]
# 限制方式二:在配置文件中寫---》全局有效
# drf的配置(在rest_framework的setting中),統(tǒng)一寫成它
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
# 'rest_framework.parsers.FormParser',
# 'rest_framework.parsers.MultiPartParser',
],
}
# 全局配置了只支持json,局部想支持3個
-只需要在局部,視圖類中,寫3個即可
class BookView(APIView):
parser_classes = [JSONParser, FormParser,MultiPartParser]
# 總結:能夠處理的請求方式編碼
-優(yōu)先從視圖類中找
-再去項目配置文件找
-再去drf默認的配置中找
5.drf之響應
5.1響應類的對象Response
# return Response({'code':100})
data:響應體的內容,可以字符串,字典,列表
status:http響應狀態(tài)碼
drf把所有響應碼都定義成一個常量
template_name:模板名字,用瀏覽器訪問,看到好看的頁面,用postman訪問,返回正常數(shù)據(jù)
-自定制頁面
-根本不用
headers:響應頭加數(shù)據(jù)(后面講跨域問題再講)
-headers={'name':'lqz'}
content_type:響應編碼,一般不用
# 三個重要的:data,status,headers
5.2響應的格式
# 默認是兩種:純json,瀏覽器看到的樣子
# 限制方式一:在視圖類上寫---》只是局部視圖類有效
# 總共有兩個:JSONRenderer,BrowsableAPIRenderer
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class BookView(APIView):
renderer_classes = [JSONRenderer]
# 限制方式二:在配置文件中寫---》全局有效
# drf的配置,統(tǒng)一寫成它
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
# 'rest_framework.renderers.BrowsableAPIRenderer',
],
}
# 全局配置了只支持json,局部想支持2個
-只需要在局部,視圖類中,寫2個即可
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class BookView(APIView):
renderer_classes = [JSONRenderer,BrowsableAPIRenderer]
6.視圖之兩個視圖基類
# 視圖類:
-APIView:之前用過
-GenericAPIView:GenericAPIView繼承了APIView
# GenericAPIView
-類屬性:
queryset:要序列化的所有數(shù)據(jù)
serializer_class:序列化類
lookup_field = 'pk' :查詢單條時的key值
-方法:
-get_queryset():獲取所有要序列化的數(shù)據(jù)【后期可以重寫】
-get_serializer : 返回序列化類
-get_object :獲取單個對象
#總結:以后繼承GenericAPIView寫接口
1 必須配置類屬性
queryset
serializer_class
2 想獲取要序列化的所有數(shù)據(jù)
get_queryset()
3 想使用序列化類:
get_serializer
4 想拿單條
get_object
6.1使用APIView+序列化類+Response寫接口
from rest_framework.views import APIView
from .serializer import BookSerialzier
from rest_framework.response import Response
from .models import Book
# class BookView(APIView):
# def get(self, request):
# qs = Book.objects.all()
# ser = BookSerialzier(qs, many=True)
# return Response({'code': 100, 'msg': '成功', 'results': ser.data})
#
# def post(self, request):
# ser = BookSerialzier(data=request.data)
# if ser.is_valid():
# ser.save()
# return Response({'code': 100, 'msg': '成功'})
# else:
# return Response({'code': 100, 'msg': ser.errors})
#
#
# class BookDetailView(APIView):
# def get(self, request, pk):
# book = Book.objects.all().get(pk=pk)
# ser = BookSerialzier(book)
# return Response({'code': 100, 'msg': '成功', 'results': ser.data})
#
# def put(self, request, pk):
# book = Book.objects.get(pk=pk)
# ser = BookSerialzier(data=request.data, instance=book)
# if ser.is_valid():
# ser.save()
# return Response({'code': 100, 'msg': '更新成功'})
# else:
# return Response({'code': 100, 'msg': ser.errors})
6.2 使用GenericAPIView+序列化類+Response寫接口
class BookView(GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerialzier
def get(self, request):
qs = self.get_queryset()
ser = self.get_serializer(qs, many=True)
return Response({'code': 100, 'msg': '成功', 'results': ser.data})
def post(self, request):
ser = self.get_serializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '成功'})
else:
return Response({'code': 100, 'msg': ser.errors})
class BookDetailView(GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerialzier
def get(self, request, pk):
book = self.get_object()
ser = self.get_serializer(book)
return Response({'code': 100, 'msg': '成功', 'results': ser.data})
def put(self, request, pk):
book = self.get_object()
ser = self.get_serializer(data=request.data, instance=book)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '更新成功'})
else:
return Response({'code': 100, 'msg': ser.errors})
文章來源地址http://www.zghlxwxcb.cn/news/detail-455199.html
文章來源:http://www.zghlxwxcb.cn/news/detail-455199.html
到了這里,關于drf——反序列化校驗源碼(了解)、斷言、drf之請求和響應、視圖之兩個視圖基類的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!