【Django】视图系统 -- 2019-08-07 10:48:28
目录
原创: http://106.13.73.98/__/36/ @ 响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。 无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你当前项目目录下面。除此之外没有更多的要求了,可以说“没什么神奇的地方”。 为了将代码存放位置统一,大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为views.py的文件中。 一个简单的视图: # 以HTML文档的形式返回当前日期和时间 from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() html = '<html><body>It is now %s.</body></html>' % now return HttpResponse(now) 让我们来逐行解释上面的代码:
FBV 与 CBVFBV (function based view) 基于函数的视图. 对于相同的逻辑,FBV与CBV的写法: from django.shortcuts import render,redirect def classes_add(request): if request.method == 'POST': add_classes_name = request.POST.get('add_classes_name') # 提取班级名称 Classes.objects.create(name=add_classes_name) # 将新建班级写入数据库 return redirect('/classes/') # 跳转至展示页面 return render(request,'classes_add.html') # 返回添加页面 # urls文件 url(r'^classes_add/$',views.classes_add), CBV from django.shortcuts import render,redirect from django.views import View class ClassesAdd(View): # 可自定义允许的请求 # http_method_names = ['get','post'] # 处理get请求的逻辑 def get(self,request): return render(request,'classes_add.html') # 返回添加页面 # 处理post请求的逻辑 def post(self,request): add_classes_name = request.POST.get('add_classes_name') # 提取班级名称 Classes.objects.create(name=add_classes_name) # 将新建班级写入数据库 return redirect('/classes/') # 跳转至展示页面 # urls文件 url(r'^classes_add/$',views.ClassesAdd.as_view()), 给视图加装饰器FBV本身就是函数,所以和给普通函数加装饰器无差异. 使用装饰器装饰CBV类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法,我们需要将其转换为方法装饰器. 装饰器函数如下: import time def wrapper(fn): def inner(*args,**kwargs): start_time = time.time() ret = fn(*args,**kwargs) end_time = time.time() print("used:",end_time - start_time) return ret return inner 装饰CBV写法如下: from django.shortcuts import render,redirect from django.views import View # 导入method_decorator from django.utils.decorators import method_decorator class ClassesAdd(View): # 处理get请求的逻辑 @method_decorator(wrapper) #! def get(self,'classes_add.html') # 返回添加页面 # 处理post请求的逻辑 @method_decorator(wrapper) #! def post(self,request): add_classes_name = request.POST.get('add_classes_name') # 提取班级名称 Classes.objects.create(name=add_classes_name) # 将新建班级写入数据库 return redirect('/classes/') # 跳转至展示页面 关于dispatch()方法使用CBV时需注意,请求过来后会先执行dispatch()方法,如果需要批量对具体的请求处理,如get、post等做一些操作的时,我们可以在子类中手动改写此方法,这种操作其实和在FBV上加装饰器的效果一样. from django.shortcuts import render,redirect from django.views import View class ClassesAdd(View): # 可自定义处理请求前后的逻辑 def dispatch(self,request,*args,**kwargs): # 处理请求之前的逻辑 ret = super().dispatch(request,**kwargs) # 处理请求之后的逻辑 return ret # 处理get请求的逻辑 def get(self,request): add_classes_name = request.POST.get('add_classes_name') # 提取班级名称 Classes.objects.create(name=add_classes_name) # 将新建班级写入数据库 return redirect('/classes/') # 跳转至展示页面 Request对象 与 Response对象request对象当一个页面被请求时,Django会创建一个包含本次请求原消息的HttpRequest对象. 请求相关的属性
其它属性所有的属性都应该被认为是只读的,除非另有说明.
上传文件实例: def upload(request): if request.method == 'POST': file_obj = request.FILES.get('file') # 获取文件对象(获取文件信息要用FILES) upload_file_path = os.path.join(settings.BASE_DIR,'upload_file',file_obj.name) # 文件上传路径,file_obj.name为str类型 # 判断文件是否存在的逻辑 if os.path.exists(upload_file_path): name,suffix = file_obj.name.split('.') # 切割文件名与文件后缀 file_name = name + "_文件副本1." + suffix # 重新拼接文件名 upload_file_path = os.path.join(settings.BASE_DIR,file_name) # 文件上传路径 # 判断文件是否有副本的逻辑 if os.path.exists(upload_file_path): file_list = os.listdir(os.path.dirname(upload_file_path)) # 获取所有副本文件 file_copy_num = [] for i in file_list: if name not in i: continue copy_num = i.split('.')[0][-1] # 提取副本数字 if copy_num == name[-1]: continue file_copy_num.append(copy_num) file_copy_max = int(max(file_copy_num)) # 提取最大的副本数字 file_name = name + "_文件副本" + str(file_copy_max + 1) + '.' + suffix upload_file_path = os.path.join(settings.BASE_DIR,file_name) # 文件上传路径 with open(upload_file_path,'wb') as f: [f.write(chunk) for chunk in file_obj.chunks()] # 从文件里一点一点的读数据,写到文件里 return HttpResponse("文件上传成功!") # 返回提示信息 return render(request,'upload.html') # 返回上传页面 方法
注意:键值对中的值为多个时(例如checkbox类型的input标签),因该使用getlist()方法. response对象与Django自动创建的HttpRequest对象相比,HttpResponse对象是我们的职责范围了,我们写的每个视图都需要实例化,填充和返回一个HttpResponse. 传递字符串: from django.http import HttpResponse response = HttpResponse("Here's the text of the Web page.") response = HttpResponse("Text only,please.",content_type="text/plain") 设置或删除响应头消息: response = HttpResponse() response['Content-Type'] = 'text/html; charset=UTF-8' del response['Content-Type'] 属性
from django.http import JsonResponse def test(request): dct = {'name': 'zyk','sex': 'boy'} response = JsonResponse(dct) print(response.content) return response 默认只会传递字典类型的数据,如果要传递非字典类型的数据,需要设置参数safe=False: response = JsonResponse([1,2,3],safe=False) 原创: http://106.13.73.98/__/36/ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |