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

python view操作 python中view函数_HTTP

python view操作 python中view函数_HTTP_02

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 —— 服务器的端口(是一个字符串)。

View Code

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.'