规定视图函数必须有一个返回值,前端
而且返回值的数据类型必须是 HttpResponse 对象python
返回浏览器一个字符串django
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。json
默认返回一个临时的重定向;传递permanent=True
能够返回一个永久的重定向。后端
扩展阅读:浏览器
临时重定向(响应状态码:302)和永久重定向(响应状态码:301)对普通用户来讲是没什么区别的,它主要面向的是搜索引擎的机器人。app
A页面临时重定向到B页面,那搜索引擎收录的就是A页面。函数
A页面永久重定向到B页面,那搜索引擎收录的就是B页面。post
前提知识点:先后端数据要交互,一般状况下采用json的字符串,后端须要写好响应的url接口并返回json格式的字符串,前端在访问你这个接口就好了。
先后端json 序列化和反序列化的方法
方法 | 后端 | 前端 |
---|---|---|
序列化 | json.dumps | JSON.stringfy |
反序列化 | json.loads | JSON.parse |
django很是友好,帮咱们想到了这个问题,就有现成的对象来自动转成json的对象---JsonResponse
# 导入JsonResponse 对象 from django.http import JsonResponse def index(request): user_dict = {'username':'qinyj','age':18,'hobby':'独角兽的好事'} # json数据序列化的时候,若是这个字典里有中文, # 那么序列化的时候就不能序列化中文了,须要加参数ensure_ascii=False return HttpResponse(json.dumps(user_dict,ensure_ascii=False)) # 一样django帮你想到了这点,直接用jsonresponse对象返回就好了,不须要导入json模块了。 # 可是一样也是不支持中文的,须要加参数json_dumps_params={'ensure_ascii':False} return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False}) L = [1,2,3,4] # json默认是序列化字典用的,若是序列化其余数据类型的话会报错: # In order to allow non-dict objects to be serialized set the safe parameter to False. # 提示必需要加safe参数 return JsonResponse(L,safe=False)
基于函数版的视图任务
def index(request): user_dict = {'username':'qinyj','age':18,'hobby':'独角兽的好事'} # json数据序列化的时候,若是这个字典里有中文, # 那么序列化的时候就不能序列化中文了,须要加参数ensure_ascii=False return HttpResponse(json.dumps(user_dict,ensure_ascii=False)) # 一样django帮你想到了这点,直接用jsonresponse对象返回就好了,不须要导入json模块了。 # 可是一样也是不支持中文的,须要加参数json_dumps_params={'ensure_ascii':False} return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False}) L = [1,2,3,4] # json默认是序列化字典用的,若是序列化其余数据类型的话会报错: # In order to allow non-dict objects to be serialized set the safe parameter to False. # 提示必需要加safe参数 return JsonResponse(L,safe=False) 而后在urls.py 路由匹配中写匹配规则 url(r'^index/', views.index)
基于类版的视图任务
# 导入View,继承View类 from django.views import View class MyLogin(View): def get(self,request): print("我是MyLog里面的get方法") return render(request,'login.html') def post(self,request): print("我是MyLog里面的post方法") return HttpResponse("post") 而后在urls.py 路由匹配中写匹配规则,CBV书写方式有所不一样 url(r'^login/', views.MyLogin.as_view()) # 经过看源码的执行流程: # 访问类的属性和方法,方法加括号,执行优先级最高 # 项目一启动 会自动执行as_views方法 # 第一步 会 变形为 views.view # url(r'login/',views.view), # 而后进入view函数 --> self.dispatch(request, *args, **kwargs) --> if request.method.lower() in self.http_method_names: # handler = getattr(self, request.method.lower(), self.http_method_not_allowed) --> return handler(request, *args, **kwargs)
咱们经过看CBV执行的流程源码看出来,能够思考一个问题,
咱们在视图中定义两个方法,get、post
为何可以根据请求方式的不一样,自动执行不一样的方法?
django CBV方式执行源码重要部分:
路由层经过匹配 url(r'^login/', views.MyLogin.as_view()) 首先遇到类名加括号,执行优先级最高,经过调用as_view获得一个返回值view,把它变形, url(r'login/',views.view) 而后执行view的方法,会到dispatch方法中执行 判断请求的方式是什么,在不在事先定义好的方法列表里面 而后利用反射获得对请求方式的对象,再次return出去,执行请求方式对象里的内容. @classonlymethod def as_view(cls, **initkwargs): """ Main entry point for a request-response process. """ ... 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) ... update_wrapper(view, cls.dispatch, assigned=()) return view def dispatch(self, request, *args, **kwargs): # 这里判断请求的方式是什么,在不在事先定义好的方法列表里面 # http_method_names = ['get', # 'post', # 'put', # 'patch', # 'delete', # 'head', # 'options', # 'trace'] 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)
FBV加装饰器的方式很简单,和以前咱们加装饰器没有区别。
# 定义一个计算执行时间的装饰器 def outter(func): @wraps(func) def inner(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs) end_time = time.time() print('执行时间:',end_time - start_time) return res return inner # 普通函数加装饰器 @outter def index(request): user_dict = {'username':'qinyj','age':18,'hobby':'独角兽的好事'} # return HttpResponse(json.dumps(user_dict,ensure_ascii=False)) # json数据序列化的时候,若是这个字典里有中文, # 那么序列化的时候就不能序列化中文了,须要加参数ensure_ascii=False # 一样django帮你想到了这点,直接用jsonresponse对象返回就好了,不须要导入json模块了。 # return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False}) L = [1,2,3,4] # json默认是序列化字典用的,若是序列化其余数据类型的话会报错: # In order to allow non-dict objects to be serialized set the safe parameter to False. # 提示必需要加safe参数 return JsonResponse(L,safe=False)
那么CBV加加装饰器如何加?
@method_decorator(outter,name='get')
outter:装饰器名称
name=:指定哪一个方法使用装饰器
# 定义一个计算执行时间的装饰器 def outter(func): @wraps(func) def inner(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs) end_time = time.time() print('执行时间:',end_time - start_time) return res return inner # 导入装饰器的模块,官方推荐写法 from django.utils.decorators import method_decorator # 第一种方式:能够指定给那个方法加 # @method_decorator(outter,name='get') # @method_decorator(outter,name='post') # @method_decorator(outter,name='dispatch') class MyLogin(View): # 第二种方式:在此重写父类dispatch方法,作一些操做,给全部的方法都加上装饰器。 @method_decorator(outter) def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) # 第三中方法:能够单独在方法名称上加装饰器 # @method_decorator(outter) def get(self,request): print("我是MyLog里面的get方法") return render(request,'login.html') def post(self,request): print("我是MyLog里面的post方法") return HttpResponse("post") 执行结果: 我是MyLog里面的get方法 执行时间: 0.01500082015991211 我是MyLog里面的post方法 执行时间: 0.0