1.django请求生命周期
进入实现wsgi协议的web服务器 ==》进入django ==》进入django的中间件==》进入路由层==》进入视图函数==》模型层取数据,模板层取模板,利用数据渲染模板==》返回模板的字符串 ==》显示页面
wsgi 和cgi(通用网关协议)
2.开发模式
前后端不分离项目:利用django的模板语法对前端进行渲染
前后端分离项目:前后端通过json数据交互
3.CBV 源码分析
路由配置:url(r'^test/', views.Test.as_view())
请求通过中间件后进入路由,根据路由匹配对应的视图函数,本质执行了as_view内部的view函数,内部调用了self.dispatch,根据请求方式的不同,执行不同的方法,(get请求,执行我们在视图函数内写的get方法)
class APIView(View):
def dispatch(self, request, *args, **kwargs):
# 写一些频率控制的东西
ret = super().dispatch(request, *args, **kwargs)
return ret
class Test(APIView):
# http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
def get(self, *args, **kwargs):
return HttpResponse('ok')
无论什么请求方式,都要经过dispatch方法,我们中间件做控制的操作,可以通过重写dispatch方法来实现,如频率的控制,身份的校验等。
4.基于原生django开发restful的接口
模型层:
class Book(models.Model):
book_name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8, decimal_places=2)
author = models.CharField(max_length=16)
publish = models.CharField(max_length=32)
视图层:
from rest_framework.views import APIView
class Book(APIView):
def get(self, request):
"""
request是被封装后的request,原生的request在request._request;
如果想用原生requset中的属性,还是原来的用法,因为Request重写了__getattr__方法;
原生django只能处理urlencoded和formdata编码,如果是json格式,原生django是不能处理的,需要自己从body中取出来自行处理;
request.data 不管前端传数据的编码格式是urlencoded,formdata或者是json,都从里面取值;
request.query_params 是原来django原生的GET中的数据;
self.FILES 就是上传的文件.
:param request:
:return:
"""
# 前后端分离需要将queryset对象转化为json格式(列表套字典)返回
books = models.Book.objects.all()
ls = [{'book_name': book.book_name, 'publish': book.publish} for book in books] # 转换为json格式
dic = {'name': 'lzp', 'age': 20, 'girl_friend': ['刘亦菲', '李一桐', '其他女友'], 'book': ls}
# 且json序列化的对象有列表需要设置safe=False
return JsonResponse(dic, safe=False, json_dumps_params={'ensure_ascii': False})
5.djangorestframework
安装:pip install djangorestframework 或pycharm搜索安装
使用了drf框架,所有的视图函数都要写成cbv的形式
使用djangorestframework,要在settings的app中注册。
INSTALLED_APPS= [
……
'rest_framework'
]
路由层:
urlpatterns = [
url(r'^admin/', admin.site.urls),
# url(r'^test/', views.Test.as_view()),
url(r'^books/', views.Books.as_view()),
]
视图层:
from rest_framework.views import APIView
class Book(APIView):
def get(self, request):
"""
request是被封装后的request,原生的request在request._request;
如果想用原生requset中的属性,还是原来的用法,因为Request重写了__getattr__方法;
原生django只能处理urlencoded和formdata编码,如果是json格式,原生django是不能处理的,需要自己从body中取出来自行处理;
request.data 不管前端传数据的编码格式是urlencoded,formdata或者是json,都从里面取值;
request.query_params 是原来django原生的GET中的数据;
self.FILES 就是上传的文件.
:param request:
:return:
"""
# 前后端分离需要将queryset对象转化为json格式(列表套字典)返回
books = models.Book.objects.all()
ls = [{'book_name': book.book_name, 'publish': book.publish} for book in books] # 转换为json格式
dic = {'name': 'lzp', 'age': 20, 'girl_friend': ['刘亦菲', '李一桐', '其他女友'], 'book': ls}
# 且json序列化的对象有列表需要设置safe=False
return JsonResponse(dic, safe=False, json_dumps_params={'ensure_ascii': False})
浏览器拿到的数据:
{"name": "lzp", "age": 18, "girl_friend": ["刘亦菲", "李一桐", "其他女友"], "book": [{"b_name": "剑来", "publish": "北京出版社"}, {"b_name": "雪中悍刀行", "publish": "上海出版社"}]}
基于drf视图函数的request:
- request是被封装后的request,原生的request在request._request;
- 如果想用原生requset中的属性,还是原来的用法,因为Request重写了__getattr__方法;
- 原生django只能处理urlencoded和formdata编码,如果是json格式,原生django是不能处理的,需要自己从body中取出来自行处理;
- request.data 不管前端传数据的编码格式是urlencoded,formdata或者是json,都从里面取值;
- request.query_params 是原来django原生的GET中的数据;
- self.FILES 就是上传的文件.
源码分析:
APIView实际继承了django的view
继承APIView之后:
1.所有的请求没有了csrf认证
2.在APIView中的as_view本质还是调用了父类的as_view
3.as_view中调用dispatch (这个dispatch实际上是APIView的dispatch)