1.寫視圖的方法
1.1第一種:原始APIView
url(r'^login/$',account.LoginView.as_view()),
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework_jwt.settings import api_settings
from rest_framework.throttling import AnonRateThrottle
from api import models
class LoginView(APIView):
authentication_classes = []
def post(self,request,*args,**kwargs):
# 1.根據用戶名和密碼檢測用戶是否能夠登陸
user = models.UserInfo.objects.filter(username=request.data.get('username'),password=request.data.get('password')).first()
if not user:
return Response({'code':10001,'error':'用戶名或密碼錯誤'})
# 2. 根據user對象生成payload(中間值的數據)
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
payload = jwt_payload_handler(user)
# 3. 構造前面數據,base64加密;中間數據base64加密;前兩段拼接而後作hs256加密(加鹽),再作base64加密。生成token
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
token = jwt_encode_handler(payload)
return Response({'code': 10000, 'data': token})
1.2第二種:ListApiView等
url(r'^article/$',article.ArticleView.as_view()),
url(r'^article/(?P<pk>\d+)/$',article.ArticleDetailView.as_view()),
from rest_framework.throttling import AnonRateThrottle
from rest_framework.response import Response
from rest_framework.generics import ListAPIView,RetrieveAPIView
from api import models
from api.serializer.article import ArticleSerializer,ArticleDetailSerializer
class ArticleView(ListAPIView):
authentication_classes = []
# throttle_classes = [AnonRateThrottle,]
queryset = models.Article.objects.all()
serializer_class = ArticleSerializer
class ArticleDetailView(RetrieveAPIView):
authentication_classes = []
queryset = models.Article.objects.all()
serializer_class = ArticleDetailSerializer
1.3第三種:
url(r'^article/$',article.ArticleView.as_view({"get":'list','post':'create'})),
url(r'^article/(?P<pk>\d+)/$',article.ArticleView.as_view({'get':'retrieve','put':'update','patch':'partial_update','delete':'destroy'}))
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin,RetrieveModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin
from api.serializer.article import ArticleSerializer,ArticleDetailSerializer
class ArticleView(GenericViewSet,ListModelMixin,RetrieveModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin):
authentication_classes = []
throttle_classes = [AnonRateThrottle,]
queryset = models.Article.objects.all()
serializer_class = None
def get_serializer_class(self):
pk = self.kwargs.get('pk')
if pk:
return ArticleDetailSerializer
return ArticleSerializer
2.drf 相關知識點梳理
2.1裝飾器
def outer(func):
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner
@outer
def index(a1):
pass
index()
def outer(func):
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner
def index(a1):
pass
index = outer(index)
index()
2.2django中能夠免除csrftoken認證
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import HttpResponse
@csrf_exempt
def index(request):
return HttpResponse('...')
# index = csrf_exempt(index)
urlpatterns = [
url(r'^index/$',index),
]
urlpatterns = [
url(r'^login/$',account.LoginView.as_view()),
]
class APIView(View):
@classmethod
def as_view(cls, **initkwargs):
view = super().as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs
# Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
return csrf_exempt(view)
2.3面向對象中基於繼承+異常處理來作的約束
class BaseVersioning:
def determine_version(self, request, *args, **kwargs):
raise NotImplementedError("must be implemented")
class URLPathVersioning(BaseVersioning):
def determine_version(self, request, *args, **kwargs):
version = kwargs.get(self.version_param, self.default_version)
if version is None:
version = self.default_version
if not self.is_allowed_version(version):
raise exceptions.NotFound(self.invalid_version_message)
return version
2.4面向對象封裝
class Foo(object):
def __init__(self,name,age):
self.name = name
self.age = age
obj = Foo('汪洋',18)
class APIView(View):
def dispatch(self, request, *args, **kwargs):
self.args = args
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs)
self.request = request
...
def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
"""
parser_context = self.get_parser_context(request)
return Request( # 給request再封裝一層
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(), # [MyAuthentication(),]
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
2.5面向對象繼承
class View(object):
pass
class APIView(View):
def dispatch(self):
method = getattr(self,'get')
method()
class GenericAPIView(APIView):
serilizer_class = None
def get_seriliser_class(self):
return self.serilizer_class
class ListModelMixin(object):
def get(self):
ser_class = self.get_seriliser_class()
print(ser_class)
class ListAPIView(ListModelMixin,GenericAPIView):
pass
class UserInfoView(ListAPIView):
pass
view = UserInfoView()
view.dispatch()
class View(object):
pass
class APIView(View):
def dispatch(self):
method = getattr(self,'get')
method()
class GenericAPIView(APIView):
serilizer_class = None
def get_seriliser_class(self):
return self.serilizer_class
class ListModelMixin(object):
def get(self):
ser_class = self.get_seriliser_class()
print(ser_class)
class ListAPIView(ListModelMixin,GenericAPIView):
pass
class UserInfoView(ListAPIView):
serilizer_class = "汪洋"
view = UserInfoView()
view.dispatch()
class View(object):
pass
class APIView(View):
def dispatch(self):
method = getattr(self,'get')
method()
class GenericAPIView(APIView):
serilizer_class = None
def get_seriliser_class(self):
return self.serilizer_class
class ListModelMixin(object):
def get(self):
ser_class = self.get_seriliser_class()
print(ser_class)
class ListAPIView(ListModelMixin,GenericAPIView):
pass
class UserInfoView(ListAPIView):
def get_seriliser_class(self):
return "咩咩"
view = UserInfoView()
view.dispatch()
2.6反射
class View(object):
def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
2.7發送ajax請求
$.ajax({
url:'地址',
type:'GET',
data:{...},
success:function(arg){
console.log(arg);
}
})
- 簡單請求,發送一次請求。
- 複雜請求,先options請求作預檢,而後再發送真正請求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>常鑫的網站</h1>
<p>
<input type="button" value="點我" onclick="sendMsg()">
</p>
<p>
<input type="button" value="點他" onclick="sendRemoteMsg()">
</p>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
function sendMsg() {
$.ajax({
url:'/msg/',
type:'GET',
success:function (arg) {
console.log(arg);
}
})
}
function sendRemoteMsg() {
$.ajax({
url:'http://127.0.0.1:8002/json/',
type:'GET',
success:function (arg) {
console.log(arg);
}
})
}
</script>
</body>
</html>
2.8如何解決ajax+跨域?
CORS,跨站資源共享,本質:設置響應頭。
2.9常見的Http請求方法
get
post
put
patch
delete
options
2.10http請求中Content-type請起頭
狀況一:
content-type:x-www-form-urlencode
name=alex&age=19&xx=10
request.POST和request.body中均有值。
狀況二:
content-type:application/json
{"name":"ALex","Age":19}
request.POST沒值
request.body有值。
2.11django中F查詢
2.12django中獲取空Queryset
models.User.object.all().none()
2.13基於django的fbv和cbv都能實現遵循restful規範的接口
def user(request):
if request.metho == 'GET':
pass
class UserView(View):
def get()...
def post...
2.14基於django rest framework框架實現restful api的開發。
- 免除csrf認證
- 視圖(APIView、ListAPIView、ListModelMinx)
- 版本
- 認證
- 權限
- 節流
- 解析器
- 篩選器
- 分頁
- 序列化
- 渲染器
2.15簡述drf中認證流程?
2.16簡述drf中節流的實現原理以及過程?匿名用戶/非匿名用戶 如何實現頻率限制?
2.17GenericAPIView視圖類的做用?
他提供了一些規則,例如:
class GenericAPIView(APIView):
serializer_class = None
queryset = None
lookup_field = 'pk'
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
def get_queryset(self):
return self.queryset
def get_serializer_class(self):
return self.serializer_class
def filter_queryset(self, queryset):
for backend in list(self.filter_backends):
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
@property
def paginator(self):
if not hasattr(self, '_paginator'):
if self.pagination_class is None:
self._paginator = None
else:
self._paginator = self.pagination_class()
return self._paginator
他至關於提供了一些規則,建議子類中使用固定的方式獲取數據,例如:
class ArticleView(GenericAPIView):
queryset = models.User.objects.all()
def get(self,request,*args,**kwargs):
query = self.get_queryset()
咱們能夠本身繼承GenericAPIView來實現具體操做,可是通常不會,由於更加麻煩。
而GenericAPIView主要是提供給drf內部的 ListAPIView、Create....
class ListModelMixin:
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
class ListAPIView(mixins.ListModelMixin,GenericAPIView):
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
class MyView(ListAPIView):
queryset = xxxx
ser...
總結:GenericAPIView主要爲drf內部幫助咱們提供增刪改查的類LIstAPIView、CreateAPIView、UpdateAPIView、提供了執行流程和功能,咱們在使用drf內置類作CURD時,就能夠經過自定義 靜態字段(類變量)或重寫方法(get_queryset、get_serializer_class)來進行更高級的定製。
2.18jwt以及其優點。
2.19序列化時many=True和many=False的區別?
2.20應用DRF中的功能進行項目開發
*****
解析器:request.query_parmas/request.data
視圖
序列化
渲染器:Response
****
request對象封裝
版本處理
分頁處理
***
認證
權限
節流
- 基於APIView實現呼啦圈
- 繼承ListAPIView+ GenericViewSet,ListModelMixin實現呼啦圈