DRF框架---第01天
项目创建
settings.py文件配置
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders', #解决跨域问题
'app01.apps.App01Config',
'amp', 注册应用
]
CORS_ORIGIN_ALLOW_ALL=True
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai' #django规定的时区
CORS跨域问题(同源策略)
同源:http协议相同、ip服务器地址相同、app应用端口相同
跨域:协议、ip地址、应用端口有一个不同,就是跨域
Django默认是同源策略,存在跨越问题。
Django的解决方案:
1)Django按照cors模块:
>: pip install django-cors-headers
2)在settings注册模块,配置中间件:
INSTALLED_APPS = [
...
'corsheaders'
]
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware'
]
3)在settings开启允许跨越:
CORS_ORIGIN_ALLOW_ALL = True
drf01---urls.py文件
from django.conf.urls import url,include
urlpatterns=[
url(r'^amp/',include('amp.urls')),
]
下面开始创建amp项目
Python manage.py startapp amp
然后amp文件创建urls.py文件
amp文件中对urls.py,models.py ,views.py文件进行书写
urls.py
from amp import views
from django.conf.urls import url,include
urlpatterns=[
drf采用CBV视图
url(r'^books/$',views.BookAPIView.as_view()),
url(r'^books/(?P<pk>\d+)/$',views.BookAPIView.as_view())
]
views.py
一个视图类可以保护常规5个请求方法: get post patch put delete
5个请求方法处理十个资源操作的逻辑:单群查 单群增 单群整体改 单群局部改 单群删
import rest_framework
from django.http import JsonResponse
from django.views import View
from django.shortcuts import render
from rest_framework.views import APIView 导入视图类
from . import models
class BookView(View):
def single_get(self,pk):
book_dic=models.Book.objects.filter(pk=pk).values('name','price').first()
if not book_dic:
return JsonResponse({
'status':1,
'msg':'单查,资源不存在'
})
return JsonResponse({
'status':0,
'msg':'单查OK',
'results':book_dic
})
def many_get(self):
book_query=models.Book.objects.values('name','price')
book_list=list(book_query)
return JsonResponse({
'status':0,
'msg':'群查OK',
'results':book_list
})
get请求方法
def get(self,request,*args,**kwargs):
pk=kwargs.get(pk)
if pk:
单查
return self.single_get(pk)
else:
群查
return self.many_get()
models.py
from django.db import models
class Book(models.Model):
name=models.CharField(max_length=32)
price=models.DecimalField(max_digits=6,decimal_places=2)
访问的接口
接口参数:
url+请求方式+项目访问路径+参数(有参单查,无参群查)
https://127.0.0.1:8000/amp/books get请求
群查
https://127.0.0.1:8000/amp/books/2 get请求
单查
DRF框架---第02天
rest_framework 框架的封装特点:
import rest_framework
from rest_framework.views import APIView
class BookAPIView(APIView):
def get(self,request,*args,**kwargs):
return Response({
'msg':'apiview get ok'
})
def post(self,request,*args,**kwargs):
return Response({
'msg':'apiview post ok'
})
导入视图类 from rest_framework.views import APIView
导入请求 from rest_framework.request import Request
导入响应 from rest_framework.response import Response
导入异常 from rest_framework.exceptions import APIException
导入分页 from rest_framework.pagination import PageNumberPagination
导入配置 from rest_framework.settings import APISettings
导入解析 from rest_framework.parsers import JSONParser
导入排序过滤器 from rest_framework.filters import OrderingFilter
1.APIView的请求生命周期
1.APIView的类继承View类,重写了as_view 和 dispatch 方法
2.重写的as_view方法,主体还是View的as_view,只是在返回视图view函数地址时,局部禁用csrf认证
3.重写的dispatch方法:
在执行请求逻辑前:请求模块(二次封装request),解析模块(三种数据包格式的数据解析)
在执行请求逻辑中:异常模块(执行出现任何异常交给异常模块处理)
在执行请求逻辑后:响应模块(二次封装response),渲染模块(响应的数据可以通过json或者页面两种方式渲染)
2.请求模块
1.将wsgi的request对象转化成drf的Request类的对象
2.封装后的request对象完全兼容wsgi的request对象,并且将元request保存在新的request._request中
3.重写格式化请求数据存放位置
拼接参数:request.query_params
数据包参数:request.data
源码分析:
入口:APIView的dispatch方法的request=self.initialize_reuqest(request,*args,**kwargs)
print(request._request.method) 在内部将wsgi的request赋值给request._request
print(request.method) 就是通过__getattr__走的是request._request.method
print(request.query_params) 走的是方法属性,就是给request._request.GET重新命名
print(request.data) 走的是方法属性,值依赖于request._full_data
3.解析模块
只处理数据包参数 -form-data , urlencoded , json
1.全局配置所有视图类的解析方式,解析配置可以配置三种
2.局部配置当前视图类的解析方式,解析配置可以配置三种
3.配置的查找顺序:局部(视图类的类属性)=》全局(settings文件的drf配置)=》默认(drf的默认配置)
解析模块作为了解,但是全局局部配置是重点
源码分析:
入口:APIView的dispatch方法的request=self.initialize_request(request,*agrs,**kwargs)
获取解析类:parsers=self.get_parsers()
进行局部全局配置查找顺序进行查找:return [parser() for parser in self.parser_classes]
4.响应模块
data:响应模块
status:响应的网络状态码
------------------------------------
template_name:drf完成前后台不分离返回页面,但是就不可以返回data--(仅作了解)
headers:响应头,一般不规定,默认
exception:一般异常响应,会佳宁其设置成true,默认false(不设置也没事)
content_type:默认的就是 application/json, 不需要处理
5.渲染模块(了解)
Postman请求结果是json格式,浏览器请求结果是页面
可以全局和局部配置
BookAPIView类代码
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
from rest_framework.renders import JsonRenderer,BrowsableAPIRenderer
from rest_framework import status
class BookAPIView(APIView):
局部配置解析类:只适用当前视图类
parser_classes = [JSONParser,FormParser,MultiPartParser]
局部配置渲染类:只使用当前视图类
render_classes = [JSONRenderer,BrowsableAPIRenderer]
def get(self,request,*args,**kwargs):
response=Response(
data={
'msg':'apiview get ok'
},
status=status.HTTP_404_NOT_FOUND,
)
print(response.data)
return response
def post(self,request,*args,**kwargs):
print(request.request.method) 在内部将wsgi的request赋值给request._request
print(request.method) 就是通过__getattr__走的是request._request.method
print(request.query_params) 走的是方法属性,就是给request._request.GET重新命名
print(request.data) 走的是方法属性,值依赖于request._full_data
return Response({
'msg':'apiview post ok'
})
drf中现在所用到过的模块和导入方法
drf中现在所用到过的模块和导入方法
import rest_framework
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.exceptions import APIException
from rest_framework.pagination import PageNumberPagination
from rest_framework.settings import APISettings
from rest_framework.parsers import JSONParser
from rest_framework.filters import OrderingFilter
from django.views import View
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
from rest_framework import status
day02内容总结
1.APIView请求生命周期
APIView的as_viewe(局部禁用csrf)=》走父级的as_view调用dispatch分发请求=》APIView自己重写了dispatch,使用自己完成分发=》分发前完成request二次封装,数据解析=》三大认证=》请求的实际响应(自己的视图类的处理分发)=》出现了异常,就会交给异常模块处理异常=》响应模块完成响应,渲染模块可以json或浏览器两种方式渲染
2.请求模块
request._request 被request完全兼容
request.query_params | request.data
3.解析模块:
局部配置:parser_classes=[JSONParser,FormParser,MultiPartParser]
全局配置:
'DEFAULT_PARSER_CLASSES':[
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
]
4.响应模块:
Response(daata=常量|列表|字典,status=网络状态码)
5.渲染模块:
局部配置:renderer_classes=[JSONRenderer,BrowsableAPIRenderer]
全局配置:
'DEFAULT_RENDERER_CLASSES':[
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',上线后尽量关闭
]
6.异常模块
settings中配置:'EXCEPTION_HANDLER':'api.exception.exception_handler'
重写exception_handler方法
一定要在settings文件中将异常模块配置自己的异常处理函数
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response
先交给drf处理客户端异常,如果结果response为none代表服务器异常,自己处理
最终一定要在日志文件中记录异常现象
def exception_handler(exc,context):
response=drf_exception_handler(exc,context)
detail ='%s - %s -%s' % (context.get('view'),context.get('request').method,exc)
if not response: 服务端错误
response=Response({'detail':detail})
else:
response.data={'detail':detail}
核心:要把response.data.get('detail')信息记录到日志文件
logger.waring(response.data.get('detail'))
return response
drf:APIView请求生命周期,请求模块,解析模块,响应模块,渲染模块