Django的views(视图)
个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。
响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。
无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你当前项目目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处,大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为views.py的文件中。
一个简单的视图
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(html)
让我们来逐行解释下上面的代码:
-
首先,我们从 django.http模块导入了HttpResponse类,以及Python的datetime库。
-
接着,我们定义了current_datetime函数。它就是视图函数。每个视图函数都使用HttpRequest对象作为第一个参数,并且通常称之为request。
注意,视图函数的名称并不重要;不需要用一个统一的命名方式来命名,以便让Django识别它。我们将其命名为current_datetime,是因为这个名称能够比较准确地反映出它实现的功能。
-
这个视图会返回一个HttpResponse对象,其中包含生成的响应。每个视图函数都负责返回一个HttpResponse对象。
Django使用请求和响应对象来通过系统传递状态。
当浏览器向服务端请求一个页面时,Django创建一个HttpRequest对象,该对象包含关于请求的元数据。然后,Django加载相应的视图,将这个HttpRequest对象作为第一个参数传递给视图函数。
每个视图负责返回一个HttpResponse对象。
CBV和FBV
FBV全称(function base view)
# 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 base view)
# 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中 url(r'^add_class/$', views.AddClass.as_view()),
给views视图加上装饰器
装饰器装饰FBV
def wrapper(func): def inner(*args, **kwargs): start_time = time.time() ret = func(*args, **kwargs) end_time = time.time() print("used:", end_time-start_time) return ret return inner # FBV版添加班级 @wrapper 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加装饰器
# CBV版添加班级 from django.views import View from django.utils.decorators import method_decorator class AddClass(View): @method_decorator(wrapper) 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/")
Request对象和Response对象
Request对象
使用方法例如:request.path_info
请求相关的常用值
path_info 返回用户访问url,不包括域名 #返回结果示例:/publisher_list/ method 请求中使用的HTTP方法的字符串表示,全大写表示。 GET 包含所有HTTP GET参数的类字典对象 POST 包含所有HTTP POST参数的类字典对象 body 请求体,byte类型 request.POST的数据就是从body里面提取到的 get_full_path() # URL中的路径和参数都能拿到
上传文件示例:


def upload(request): """ 保存上传文件前,数据需要存放在某个位置。默认当上传文件小于2.5M时,django会将上传文件的全部内容读进内存。从内存读取一次,写磁盘一次。 但当上传文件很大时,django会把上传文件写到临时文件中,然后存放到系统临时文件夹中。 :param request: :return: """ if request.method == "POST": # 从请求的FILES中获取上传文件的文件名,file为页面上type=files类型input的name属性值 filename = request.FILES["file"].name # 在项目目录下新建一个文件 with open(filename, "wb") as f: # 从上传的文件对象中一点一点读 for chunk in request.FILES["file"].chunks(): # 写入本地文件 f.write(chunk) return HttpResponse("上传OK") 上传文件示例代码
注意事项
1. 如果有上传文件,views.py中应该从request.FILES中取上传的文件对象 2. 如果有上传文件,html文件中的form表单一定要加 enctype="multipart/form-data" file_obj = request.FILES.get("touxiang") # 拿到上传文件对象 file_name = file_obj.name # 拿到文件名 with open(file_name, "wb") as f: # 在本地新建一个同名文件 for line in file_obj.chunks(): # 从上传的文件对象中一点一点读取数据 f.write(line) # 写到新建的文件中
Response对象
使用
JsonResponse Django封装的一个专门用来返回JSON格式数据的方法 from django.http import JsonResponse JsonResponse(字典) JsonResponse(列表,safe=False)
传递字符串
from django.http import HttpResponse response = HttpResponse("Here's the text of the Web page.") response = HttpResponse("Text only, please.", content_type="text/plain")
示例:
def test(request): data = {'name':'98k','age':18} import json # return HttpResponse(json.dumps(data)) # return JsonResponse(data) #返回一个字典给页面 list1 =[1,3,5,7,9] return JsonResponse(list1,safe=False) #强行返回一个列表 必须加上safe=False
Django shortcut functions
render()
常用参数 参数: request: 用于生成响应的请求对象。 template_name:要使用的模板的完整名称,可选的参数 context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。 content_type:生成的文档要使用的MIME类型。默认为 DEFAULT_CONTENT_TYPE 设置的值。默认为'text/html' status:响应的状态码。默认为200。 useing: 用于加载模板的模板引擎的名称。
简单的例子:
from django.shortcuts import render def my_view(request): # 视图的代码写在这里 return render(request, 'myapp/index.html', {'foo': 'bar'})
上面的代码等于:
from django.http import HttpResponse from django.template import loader def my_view(request): # 视图代码写在这里 t = loader.get_template('myapp/index.html') c = {'foo': 'bar'} return HttpResponse(t.render(c, request))
redirect()
参数:
参数可以是: 一个模型:将调用模型的get_absolute_url() 函数 一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称 一个绝对的或相对的URL,将原封不动的作为重定向的位置。 默认返回一个临时的重定向;传递permanent=True 可以返回一个永久的重定向。 示例: 你可以用多种方式使用redirect() 函数。 传递一个具体的ORM对象(了解即可) 将调用具体ORM对象的get_absolute_url() 方法来获取重定向的URL: