视图层
三板斧问题
在视图函数中写函数跟普通函数不太一样,Django中使用的是局部的request
所有的视图函数不能够没有返回值,并且返回值还必须是HttpResponse对象
# 错误代码 The view app01.views.index didn't return an HttpResponse object. It returned None instead.
其实我们的三板斧方法返回的都是HttpResponse对象
def index(request): return HttpResponse('hello world')
在flask中request使用的是全局的request
from ... import request def index(): pass def func(): pass
JsonResponse序列化
json格式的数据?
主要就是实现跨语言数据传输
现在实现跨语言数据传输的都是json,在以前使用的是xml
微信支付朝微信的后端发送参数的时候,使用的就是xml
# json格式的数据特点: {"username":"kevin","age":18} # 是以字符串形式保存的 # 之前学的如何序列化? import json json.dumps ------------------->JSON.stringify() json.loads ------------------->JSON.parse() # 在JS中是如何做的 JSON.stringify() JSON.parse()
在Django中如何去序列化
# js中的对象 obj = new Object() # {} obj = {} # {} obj.username = 'kevin' # {'username':'kevin'} consolo.log(obj.username) from django.http import JsonResponse def index(request): # return render(request, 'index.html') # return HttpResponse("index") # 追代码----》点进去这个方法去看源码 # return render(request, "index.html", context={}) # return redirect() d = {'username': 'kevin哈喽', 'age': 18} # In order to allow non-dict objects to be serialized set the safe parameter to False. l = [1, 2 , 3, 4] # 序列化列表 return JsonResponse(l,safe=False) # 如何去序列化,以前的方法 import json # d_json = json.dumps(d,ensure_ascii=False) # 字符串 # res = JsonResponse(d_json) # print(res) # <JsonResponse status_code=200, "application/json"> # return HttpResponse(d_json) # 序列化并且转码表示中文 return JsonResponse(d, json_dumps_params={'ensure_ascii': False})
form表单上传文件
普通版本
def ad_files(request): # 接收提交的文件数据 # POST只能够获取到post请求的普通数据,拿不到文件数据 print(request.POST) # <QueryDict: {}> # 接收文件数据 print(request.FILES) # <MultiValueDict: {'my_file': [<InMemoryUploadedFile: 弥豆子.jpg (image/jpeg)>]}> if request.method == 'POST': # 获取文件数据 file_obj = request.FILES.get('my_file') # 上传 with open(file_obj.name, 'wb') as z: for line in file_obj: z.write(line) return render(request, 'ad_files.html')
随机文件名版本
# 生成随机字符串 def get_random(request): random.seed() # 重新生成随机数种子 r_int = str(random.randint(1, 9)) r_str_upper = str(chr(random.randint(65, 90))) r_str_lower = str(chr(random.randint(97, 122))) r_str = '' for i in range(5): c_str = random.choices([r_int, r_str_upper, r_str_lower]) r_str += ''.join(c_str) return r_str def ad_files(request): # 接收提交的文件数据 # POST只能够获取到post请求的普通数据,拿不到文件数据 print(request.POST) # <QueryDict: {}> # 接收文件数据 print(request.FILES) # <MultiValueDict: {'my_file': [<InMemoryUploadedFile: 弥豆子.jpg (image/jpeg)>]}> if request.method == 'POST': # 获取文件数据 file_obj = request.FILES.get('my_file') # 拿到上面写的随机字符串 ran_str = get_random(request) # 将随机字符串和文件名拼在一起,防止上传文件名出现重复 file_name = ran_str + file_obj.name # 上传 with open(file_name, 'wb') as z: for line in file_obj: z.write(line) return render(request, 'ad_files.html')
request对象的其他前几个方法
def z_request(request): print(request.path) # /z_request/只能拿到地址 print(request.path_info) # /z_request/只能拿到地址 print(request.get_full_path()) # /z_request/?username=kevin&age=11 能拿到地址和后面的参数 return HttpResponse('z_request')
request.body # 现在先不学,它能够接收浏览器发过来的二进制数据,BBS项目中学
C(class)BV的书写和F(function)BV的写法
# 目前写的都是 FBV:function based view 基于函数的师徒 # 在视图文件中书写类 CBV: class based view 基于类的视图 ''' postman的官网地址:https://www.postman.com/downloads/ apizza的挂网地址:http://www.apizza.net/ ''' # 所有的类必须继承django的view类 from django.views import View # 路由写法 # CBV的路由 url('^login/', views.MyLogin.as_view()), class MyLogin(View): # 类里面的方法名字不能够随便写,目前只能写get post等 # 访问这个地址必须是get请求方式 def get(self, request): # get() takes 1 positional argument but 2 were given print("get") return HttpResponse("get") # 访问这个方法必须是psot请求方式 # 通过form表单发送post请求 # 出了form表单,我们还可以使用工具来模拟 def post(self,request): print("post") return HttpResponse("post")
CBV的源码分析
# 我们第一次看Django的源码,面试题:你都看过Django的哪些源码,简单说说? # CBV的源码、settings的源码、权限、频率、认证的、签发token的源码 看源码的步骤是先找到源码的入口 CBV的入口在哪里呢? path('login/', views.MyLogin.as_view()), views.MyLogin.as_view() """ 类名可以调用哪些方法: 1. 方法被@classmethod装饰器修饰的方法 类名来调用类方法有什么特殊之处: 会把类名自动当成第一个参数传递给方法的第一个形参cls 对象调用方法把对象自己当成第一个参数传给方法的第一个形参self 2. 被@staticmethod装饰器修饰的方法 """ # 回头复习面向对象的方法调用 # 第一步 @classonlymethod def as_view(cls, **initkwargs): # cls:MyLogin def view(request, *args, **kwargs): self = cls(**initkwargs) if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.setup(request, *args, **kwargs) if not hasattr(self, 'request'): raise AttributeError( "%s instance has no 'request' attribute. Did you override " "setup() and forget to call super()?" % cls.__name__ ) return self.dispatch(request, *args, **kwargs) return view # 第二步: path('login/', View.view), # 第三步: 当请求来的时候,开始匹配路由login,就会调用View.view() # 第四步 def view(request, *args, **kwargs): # self = MyLogin(**initkwargs) self = cls(**initkwargs) """ self: MyLogin() """ return self.dispatch(request, *args, **kwargs) # 这句话是最重要的 # 第五步:self.dispatch(request, *args, **kwargs) # 第六步:找到了View类里面的dispatch方法 第七步: def dispatch(self, request, *args, **kwargs): # getattr: 反射 # 反射 # getattr setattr delattr hasattr # handler = getattr(self, 'get', self.http_method_not_allowed) # handler = getattr(self, 'post', self.http_method_not_allowed) # handler就是方法名,对象 # hander = get # hander = post # hander = self.http_method_not_allowed 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) # 问题:如何让我写的CBV类只支持get请求或者只支持post请求? 源码是用来看的,不是用来改的,有时候也能够改,但是你不行,你这个阶段先不要想着改人家源码的 class MyLogin(View): http_method_names = ['get',] # 类里面的方法名字不能够随便写,目前只能写get post等 # 访问这个地址必须是get请求方式 def get(self, request): # get() takes 1 positional argument but 2 were given print("get") return HttpResponse("get")
模板层
模板变量之分配
模板中取值一定要使用句点符 .
模板中的函数一定不能够加括号
# views def func(request): d = {'username': 'jack'} a = 1 b = 1.1 c = 'hello boy' e = [1, 2, 3] f = (1, 2, 3) g = True h = {1, 2, 3} def index(): print('index') return 'index' class login(): print('login') def index(self): return 'login.index' return render(request, 'func.html', locals()) # html <body> {{ a }} {{ b }} {{ c }} {{ d }} {{ e.1 }} {{ f.2 }} {{ g }} {{ h }} {{ index }} {{ login.index }} </body> # 结果 # 1 1.1 hello boy {'username': 'jack'} 2 3 True {1, 2, 3} index login.index
模板之过滤器
# Django自带的过滤器有好几十、但是我们没必要全部记住,只需要记住几个就行了 语法: {{ obj|过滤器名称:参数 }} 变量名字|过滤器名称:变量 案例: # html {#判定res的值,为False就执行default后面的#} {{ res|default:'你好啊' }} {#计算长度,无法计算就返回0#} {{ res_len|length }} {#返回数字对应的'人类可读的'文件大小#} {{ res_size|filesizeformat }} {#前段返回日期格式时间#} {{ res_data|date:'Y-m-d H:m:s' }} {#截取字符串,后面的用...代替#} {{ res_trunc|truncatechars:9 }} {#将字符串形式的前端语句生效#} {{ res_safe|safe }} {{ res_html }} # views def z_filter(request): res = True res_len = 'hello' res_size = 199999 import datetime res_data = datetime.datetime.now() res_trunc = 'hello good boy' # 后端生效前端代码 res_safe = '<h1>safe</h1>' # 第二种方式 from django.utils.safestring import mark_safe res_html = mark_safe('<h2>html</h2>') return render(request, 'z_filter.html', locals())
标签:return,get,Python,res,self,request,视图,Django,def From: https://www.cnblogs.com/zfq132/p/17598926.html