python web框架篇:views视图函数
Django请求的生命周期是怎样的?
简单地说,通过URL对应关系匹配 ->找到对应的函数(或者类)->返回字符串(或者读取Html之后返回渲染的字符串)
解剖起来如下:
1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端,请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post,体现在url之中.
2. url经过Django中的wsgi,再经过Django的中间件,最后url到过路由映射表,在路由中一条一条进行匹配,,一旦其中一条匹配成功就执行对应的视图函数,后面的路由就不再继续匹配了.
3. 视图函数根据客户端的请求查询相应的数据.返回给Django,然后Django把客户端想要的数据做为一个字符串返回给客户端.
4. 客户端浏览器接收到返回的数据,经过渲染后显示给用户.
1. 路由系统
为了给一个应用设计URL,你需要创建一个Python 模块,通常称为URLconf(URL configuration)。这个模块是纯粹的Python 代码,包含URL 模式(简单的正则表达式)到Python 函数(你的视图)的简单映射。因为它是纯粹的Python 代码,它可以动态构造。
URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表;以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码
urlpatterns = [ url(正则表达式, views视图函数,参数,别名), ] 参数说明: 一个正则表达式字符串 一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串 可选的要传递给视图函数的默认参数(字典形式) 一个可选的name参数 from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003),#1、单一路由对应 url(r'^articles/([0-9]{4})/$', views.year_archive),#2、基于正则的路由 url(r'^manage/(?P<name>\w*)', views.manage,{'id':333}),#3、添加额外的参数 url(r'^index/(\d*)', views.index, name='h2'),#4、为路由映射设置名称
设置名称之后,可以在不同的地方调用,如:
from django.conf.urls import url from . import views urlpatterns = [ #... url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'), #... ]
模板中使用生成URL
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a> <ul> {% for yearvar in year_list %} <li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li> {% endfor %} </ul>
函数中使用生成URL
from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect def redirect_to_year(request): # ... year = 2006 # ... return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))
Model中使用获取URL 自定义get_absolute_url() 方法
2. views函数
http请求中产生两个核心对象:
http请求:HttpRequest对象
http响应:HttpResponse对象
2.1 HttpRequest对象的属性和方法:
path:个字符串,表示请求的页面的完整路径,不包含域名。
例如:"/music/bands/the_beatles/"
HttpRequest.path_info
在某些Web 服务器配置下,主机名后的URL 部分被分成脚本前缀部分和路径信息部分。path_info 属性将始终包含路径信息部分,不论使用的Web 服务器是什么。使用它代替path 可以让代码在测试和开发环境中更容易地切换。
例如,如果应用的WSGIScriptAlias 设置为"/minfo",那么当path 是"/minfo/music/bands/the_beatles/" 时path_info 将是"/music/bands/the_beatles/"。
method:请求中使用的HTTP方法的字符串表示。全大写表示。
GET:包含所有HTTPGET参数的类字典对象
POST:包含所有HTTPPOST参数的类字典对象
例如
ifreq.method=="GET":
do_something()
elseif req.method=="POST":
do_something_else()
服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过HTTPPOST方法提交请求,但是表单中可能没有数据,因此不能使用ifreq.POST来判断是否使用了HTTPPOST方法;应该使用ifreq.method=="POST"
COOKIES:包含所有cookies的标准Python字典对象;keys和values都是字符串。
FILES:包含所有上传文件的类字典对象;FILES中的每一个Key都是<inputtype="file"name=""/>标签中
name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:
filename:上传文件名,用字符串表示
content_type:上传文件的ContentType
content:上传文件的原始内容
user:是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前
没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你
可以通过user的is_authenticated()方法来辨别用户是否登陆:
ifreq.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
时该属性才可用
session:唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。
HttpRequest.META
1 HttpRequest.META 2 一个标准的Python 字典,包含所有的HTTP 头部。具体的头部信息取决于客户端和服务器,下面是一些示例: 3 4 CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。 5 CONTENT_TYPE —— 请求的正文的MIME 类型。 6 HTTP_ACCEPT —— 响应可接收的Content-Type。 7 HTTP_ACCEPT_ENCODING —— 响应可接收的编码。 8 HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。 9 HTTP_HOST —— 客服端发送的HTTP Host 头部。 10 HTTP_REFERER —— Referring 页面。 11 HTTP_USER_AGENT —— 客户端的user-agent 字符串。 12 QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。 13 REMOTE_ADDR —— 客户端的IP 地址。 14 REMOTE_HOST —— 客户端的主机名。 15 REMOTE_USER —— 服务器认证后的用户。 16 REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。 17 SERVER_NAME —— 服务器的主机名。 18 SERVER_PORT —— 服务器的端口(是一个字符串)。
HttpRequest.get_full_path()
返回path,如果可以将加上查询字符串。
例如:"/music/bands/the_beatles/?print=true"
,比如:http://127.0.0.1:8000/index33/?name=123,
QueryDict.getlist(key, default)以Python 列表形式返回所请求的键的数据。如果键不存在并且没有提供默认值,则返回空列表。它保证返回的是某种类型的列表,除非默认值不是列表。
2.2 HttpResponse对象:
对于HttpRequest对象来说,是由django自动创建的,但是,HttpResponse对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse对象。
HttpResponse类在django.http.HttpResponse
在HttpResponse对象上扩展的常用方法:
1)传递字符串:典型的应用是传递一个字符串作为页面的内容到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")
2)传递迭代器
最后你可以传递给HttpResponse 一个迭代器而不是字符串. HttpResponse 将立即处理这个迭代器, 把它的内容存成字符串,并丢弃它
如果你需要从迭代器到客户端的数据数据流的形式响应, 你必须用StreamingHttpResponse 类代替;.
3)页面跳转: redirect(
"路径"
)
4)render
from django.shortcuts import render render(request, template_name, context=None, content_type=None, status=None, using=None)
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。
通俗的讲就是把context的内容, 加载进templates中定义的文件, 并通过浏览器渲染呈现.
request: 是一个固定参数, 没什么好讲的。 template_name: templates 中定义的文件, 要注意路径名. 比如'templates\polls\index.html', 参数就要写‘polls\index.html’ context: 要传入文件中用于渲染呈现的数据, 默认是字典格式 content_type: 生成的文档要使用的MIME 类型。默认为DEFAULT_CONTENT_TYPE 设置的值。 status: http的响应代码,默认是200. using: 用于加载模板使用的模板引擎的名称。
一旦你创建一个 Template 对象,你可以用 context 来传递数据给它。 一个context 是一系列变量和它们值的集合。
context 在 Django 里表现为 Context 类,在 django.template 模块里。它的构造函数带有一个可选的参数: 一个字典映射变量和它们的值。 调用 Template 对象 的 render() 方法并传递 context 来填充模板:
>>> from django.template import Context, Template >>> t = Template('My name is {{ name }}.') >>> c = Context({'name': 'greg'}) >>> t.render(c) u'My name is greg.'