以下原文来自:苑老师的blog
目前正在学习老师的Django课程,受益匪浅。
基本定义
视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。
将视图放置在项目或应用程序目录中的名为 views.py 的文件中。
示例:下面是返回当前日期和时间作为HTML文档的视图:
from django.shortcuts import render, HttpResponse, HttpResponseRedirect, redirect
import datetime
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
让我们逐行阅读上面的代码:
首先,我们从 django.shortcuts模块导入了HttpResponse类,以及Python的datetime库。
接着,我们定义了current_datetime函数。它就是视图函数。每个视图函数都使用HttpRequest对象作为第一个参数,并且通常称之为request。
注意,视图函数的名称并不重要;不需要用一个统一的命名方式来命名,以便让Django识别它。我们将其命名为current_datetime,是因为这个名称能够精确地反映出它的功能。
这个视图会返回一个HttpResponse对象,其中包含生成的响应。每个视图函数都负责返回一个HttpResponse对象。
视图层,熟练掌握两个对象即可:请求对象(request)和响应对象(HttpResponse)
一、HttpRequest对象
1、request属性
django将请求报文中的请求行、首部信息、内容主体封装成 HttpRequest 类中的属性。 除了特殊说明的之外,其他均为只读的。
2、request常用方法
1.HttpRequest.get_full_path()
返回 path,如果可以将加上查询字符串。
例如:"/music/bands/the_beatles/?print=true"
2.HttpRequest.is_ajax()
如果请求是通过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()括号内直接跟一个具体的字符串作为响应体,比较直接很简单,所以这里主要介绍后面两种形式。
1、render()
render(request, template_name[, context])
参数释义:
request: 用于生成响应的请求对象。
template_name:要使用的模板的完整名称,可选的参数
context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。
render方法就是将一个模板页面中的模板语法进行渲染,最终渲染成一个html页面作为响应体。
2、redirect()
传递要重定向的一个硬编码的URL
def my_view(request):
...
return redirect('/some/url/')
也可以是一个完整的URL:
def my_view(request):
...
return redirect('http://example.com/')
key:两次请求
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页面错误信息,访问流量白白丧失;再者某些注册了多个域名的网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点等。
用redirect可以解释APPEND_SLASH的用法!
以上原文来自:苑老师的blog
以下是自己的练习和笔记:
运行环境:
Python 3.7
Django 版本:1.8.2
项目名\urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^index/', views.index),
url('login/', views.login),
url('admin/', admin.site.urls),
]
这里初次运行python manage.py runserver后出现报错:No module named ‘django.urls’ 解决办法如下:
将原始代码:
from django.urls import admin
from django.urls import path
修改为如下即可:
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
...
url('admin/', admin.site.urls),
]
项目名\app名\views.py
from django.shortcuts import render, HttpResponse, redirect
def index(request):
print(request.method) # 打印请求的方式
"""
响应对象主要有三种形式:
1 HttpResponse("字符串")
2 render("页面")
-- 读取文本字符串
-- 渲染变量
3 redirect() # 重定向
模板语法:
{{}}
{%%}
"""
shangpin_list = ["苹果","香蕉","梨子"] # 多个商品 列表形式
return render(request, "index.html",{"sp":shangpin_list},) # 渲染变量
def login(request):
print("method", request.method) # 打印请求的方式: GET
if request.method=="GET":
return render(request, "login.html") # render方法
else:
print("method", request.method)
print(request.POST)
user = request.POST.get("user")
pwd = request.POST.get("pwd")
print(user,pwd) # 打印用户名和密码
if user=="cy" and pwd=="123":
return redirect("/index/") # 重定向
# return render(request, "index.html") # 再次返回渲染,这样毫无意义
return HttpResponse("wrong!")
项目名\templates\login.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Mysite</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/commons.css" />
</head>
<body>
<form action="/login/" method="post">
用户名 <input type="text" name="user">
密码 <input type="password" name="pwd">
<input type="submit">
</form>
</body>
</html>
项目名\templates\index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Mysite</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/commons.css" />
</head>
<body>
<h3>商品信息</h3>
<p>{{ sp }}</p> <!--列表样式-->
</body>
</html>
结果:在浏览器中测试正常,login 页面点击提交原本应该链接到的页面被重定向到了index页面: