django视图层
视图层
views.py
JsonResponse
前后端分离的情况下,通常采用json文件进行交互.
通常使用字典+开发文档的形式交互.
JsonResponse对象是HttpResponse对象的子类.
前后端序列化对比
Python | JavaScript |
---|---|
json.dumps | JSON.stringify |
json.loads | JSON.parse |
def index(request):
user_dic = {'name':'jason好帅哦 我好喜欢~','password':'123'}
# 让json不自动帮你对中文进行转码 ensure_ascii参数
# json_str = json.dumps(user_dic,ensure_ascii=False)
# return HttpResponse(json_str)
# return JsonResponse(user_dic,json_dumps_params={'ensure_ascii':False})
l = [1,2,3,4,5,6,7,]
# JsonResponse默认是序列化字典用的 如果你想序列化其他数据类型(json模块能够序列化的) 你需要加一个safe参数
return JsonResponse(l,safe=False)
FBV(function bases views)
基于函数的视图
# FBV版添加班级
def add_class(request):
if request.method == "POST":
class_name = request.POST.get("class_name")
models.Classes.objects.create(name=class_name)
return redirect("/class_list/")
return render(request, "add_class.html")
CBV(class bases views)
基于类的视图
# CBV版添加班级
from django.views import View
class AddClass(View):
def get(self, request):
return render(request, "add_class.html")
def post(self, request):
class_name = request.POST.get("class_name")
models.Classes.objects.create(name=class_name)
return redirect("/class_list/")
在使用CBV时,urls.py中也做对应的修改
# urls.py中
url(r'^add_class/$', views.AddClass.as_view()),
CBV源码流程
#utls.py中开始
urlpatterns = [
url(r'^login/',views.MyLogin.as_view()),
]
#调用login后,去views的MyLogin找as_view()方法
#views.py
class MyLogin(View):
def get(self,request):
print('我是MyLogin里面的get方法')
return render(request,'login.html')
def post(self,request):
print('我是MyLogin里面的post方法')
return HttpResponse('post')
'''
1.没有找到,再去MyLogin的父类View中找as_view()找
2.在as_view中找到类方法,其返回值为view,
3.在view中将request,args,kwargs赋值,并调用dispatch函数
4.在dispathch中,通过反射getattr得到request.method方法并返回
5.回到views.py中在MyLogin中调用对应函数
'''
#base.py
@classonlymethod
def as_view(cls, **initkwargs):
"""
Main entry point for a request-response process.
"""
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError("You tried to pass in the %s method name as a "
"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
if not hasattr(cls, key):
raise TypeError("%s() received an invalid keyword %r. as_view "
"only accepts arguments that are already "
"attributes of the class." % (cls.__name__, key))
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)
view.view_class = cls
view.view_initkwargs = initkwargs
# take name and docstring from class
update_wrapper(view, cls, updated=())
# and possible attributes set by decorators
# like csrf_exempt from dispatch
update_wrapper(view, cls.dispatch, assigned=())
return view
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)
总结
1.调用login后,去views的MyLogin找as_view()方法
2.没有找到,再去MyLogin的父类View中找as_view()找
3.在as_view中找到类方法,其返回值为view,
4.找到as_view内层函数view
5.在view中将request,args,kwargs赋值,并调用dispatch函数
6.在dispathch中,通过反射getattr得到request.method方法并返回
7.handler为1/8methde_names,并传入对应函数调用
8.回到views.py中执行对应函数
CBV装饰器
使用内置装饰器
#装饰器
def outter(func):
@wraps(func)
def inner(*args,**kwargs):
start_time = time.time()
res = func(*args,**kwargs)
end_time = time.time() - start_time
print('函数执行时间:%s'%end_time)
return res
return inner
from django.utils.decorators import method_decorator
# 2.可以指定给谁装
# @method_decorator(outter,name='post')
# @method_decorator(outter,name='dispatch')
class MyLogin(View):
@method_decorator(outter)
def dispatch(self, request, *args, **kwargs): # 覆盖父类dispathch方法来是实现
return super().dispatch(request,*args,**kwargs)
# @outter # 1.直接写
# @method_decorator(outter) # 1.推荐写法
def get(self,request):
print('我是MyLogin里面的get方法')
return render(request,'login.html')
# @outter
def post(self,request):
print('我是MyLogin里面的post方法')
time.sleep(1)
return HttpResponse('post')