Django-视图层
Django-视图层
视图函数
一个视图函数,简称视图,是一个简单的Python函数,它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片...任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。
代码写在哪里也无所谓,只要它在你的Python目录下面。约定将视图放置在项目或应用程序目录中的名为views.py的文件中
from django.shortcuts import render, HttpResponse, redirect import datetime def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
- 每个视图函数都使用HttpRequest对象作为第一个参数,并且通常称之为request
- 每个视图函数都负责返回一个HttpResponse对象
- 视图函数的名称并不重要,不需要用一个统一的命名方式来命名,以便让Django识别它。我们将其命名为current_datetime,是因为这个名称能够精确地反映出它的功能
视图层,熟练掌握两个对象即可:请求对象(HttpRequest)和响应对象(HttpResponse)
HttpRequest对象
request属性
1. request.method 一个字符串,表示HTTP请求方式:GET/POST 2. request.path 一个字符串,表示请求路径(不含域名),例如:"/music/bands/the_beatles/" 3. request.GET 一个类似于字典的对象,包含HTTP GET的所有参数,详情参考QueryDict对象 4. request.POST 一个类似于字典的对象,如果请求中包含表单数据,刚将这些数据封装成QueryDict对象
POST请求可以带有空的POST字典:如果通过HTTP POST方法发送一个表单,但是表单没有任何数据,QueryDict对象依然会被创建。因此,不应该使用if request.POST 来检查使用的是否是POST方法;应该使用
if request.method == 'POST'
另外:如果使用POST上传文件的话,文件信息将包含在FILES属性中
获取request.GET/request.POST内容:
1) 如果 print(request.POST) # <QueryDict: {"user": ["ethan"], "pwd": ["123"]}>
user = request.POST.get("user") # ethan
pwd = request.POST.get("pwd") # 123
2)如果 print(requst.POST) # <QueryDict: {"user": ["ethan", "linda"], "pwd": ["123"]}>
user = request.POST.get("user") # linda 取最后一个
3)键值对的值是多个时,需要用 request.POST.getlist()
5. request.body 一个字符串,代表请求报文的主体(请求体原生数据,例如:b"user=Ethan&pwd=123")。在处理非HTTP形式的报文时非常有用,例如:二进制图片、XML、Json等。 但是,如果要处理表单数据时,推荐还是使用request.POST 6. request.META 一个标准的Python字典,包含所有的HTTP首部。具体的头部信息取决于客户端和服务器 CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。 CONTENT_TYPE —— 请求的正文的MIME 类型。 HTTP_ACCEPT —— 响应可接收的Content-Type。 HTTP_ACCEPT_ENCODING —— 响应可接收的编码。 HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。 HTTP_HOST —— 客服端发送的HTTP Host 头部。 HTTP_REFERER —— Referring 页面。 HTTP_USER_AGENT —— 客户端的user-agent 字符串。 QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。 REMOTE_ADDR —— 客户端的IP 地址。 REMOTE_HOST —— 客户端的主机名。 REMOTE_USER —— 服务器认证后的用户。 REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。 SERVER_NAME —— 服务器的主机名。 SERVER_PORT —— 服务器的端口(是一个字符串)。 从上面可以看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,请求中的任何 HTTP 首部转换为 META 的键时, 都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_ 前缀。 所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。
request常用方法
1. request.get_full_path() 返回完整path,例如:"/music/bands/the_beatles/?print=true" 2. request.is_ajax() 返回True/False 如果请求是通过XMLHttpRequest 发起的,则返回True,方法是检查 HTTP_X_REQUESTED_WITH 相应的首部是否是字符串'XMLHttpRequest'。 大部分现代的 JavaScript 库都会发送这个头部。如果你编写自己的 XMLHttpRequest 调用(在浏览器端),你必须手工设置这个值来让 is_ajax() 可以工作。 如果一个响应需要根据请求是否是通过AJAX 发起的,并且你正在使用某种形式的缓存例如Django 的 cache middleware, 你应该使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 装饰你的视图以让响应能够正确地缓存。
HttpResponse对象
响应对象主要的三种形式:
- HttpResponse()
- render()
- redirect()
HttpResponse()括号内直接跟一个具体的字符串作为响应体。
render()
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的HttpResponse对象
render(request, template_name[, context)
参数:
- request:用于生成响应的请求对象
- template_name:要使用的模板的完整名称,可选的参数
- context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它
render方法就是将一个模板页面中的模板语法进行渲染,最终渲染成一个html页面作为响应
redirect()
特点: 两次请求
传递要重定向的一个硬编码的URL
def my_view(request): ... return redirect("/some/url/")
也可以是一个完整的URL
def my_view(request): ... return redirect("http://example.com/")
1)301和302的区别。 301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取 (用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。 他们的不同在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址; 302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。 SEO302好于301 2)重定向原因: (1)网站调整(如改变网页目录结构); (2)网页被移到一个新地址; (3)网页扩展名改变(如应用需要把.php改成.Html或.shtml)。 这种情况下,如果不做重定向,则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息,访问流量白白丧失;再者某些注册了多个域名的网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点等。