将一个请求的URL和结果的相应联系起来的机制就是任何Web开发框架的关键所在。
django的URLconf文件都必须有一个名为urlpattern的对象,这个对象的值为patterns函数返回的结果;
每个patterns函数由两种数据类型构成:一个是打头的前缀字符串,可以为空;另外可以有一个或者多个正则表达式字符串匹配一个或者一组url组成的python tuple,一个视图函数对象或字符串,有时会是一个视图函数的字典参数;
from django.conf import urls
urlpatterns = pattern('myproject.myapp.views',
url(r'^$','index',name='index')
url(r'^archives/(?P<year>\d(4))/(?P<month>\d(2))/(?P<day>\d(2))/$','archive',name='archive'),
)
正则表达式中^代表开头,$代表结尾,全部都省略了'/'符号;
index 表示前面的正则表达式所链接的函数,也就是说点击全面正则表达式的匹配的url就会调用后面的函数,第一行就是调用,myproject/myapp/views.py下面的index 函数;
name参数是可选的,就是一个字符串;
可以在一个urls.py文件里构建多个urlpatterns ,但是后面加入的urlpatterns都要用 +=符号;
如:
urlpatterns += patterns(‘myproject.catalog.views,
url(r'^catalog/$','index'),
)
如果有多个业务逻辑可以通过包含进行分离url
from django.conf import urls
from myproject.myapp import views
urlpatterns = patterns('',
url(r'^$',views.index()),
url(r'^blog/',include('myproject.blog.urls')),
)
并且 url指向的路径可以不用字符串指定,将要用到的函数的view路径引进来,这样就可以直接写上函数名而不是字符串;
HTTP建模:请求,相应和中间件:
请求对象:所有的视图函数都接受一个“请求”参数HttpRequest对象。经过良好的封装,是从WEB服务器传送过来的原始HTTP请求。请求对象主要有以下几个方面:
GET和POST字典:
在python中的表现形式为HttpRequest对象的属性(request.GET和request.POST),和python内置字典类型非常相似。
GET的参数是用户传进来的URL的一部分,但是并没有在View.py里定义相对应的类,只是在原来返回视图上做了一些小的行为,比如说,在论坛浏览帖子的时候,我希望只浏览第二页,这样GET变量传进来的url类似于:/list/?page=2。但是我们在代码里面通过读取传进来的request字典来得到用户想要浏览的具体页面,代码如下(paeinated_list_page用来显示具体页面的内容):
def list(request):
return paginated_list_page(page = request.get['page'])
POST参数不属于URL的一部分,通常用户点击了某个按钮,就会触发POST方法将FORM表单的内容发送至服务器。
cookies 和sessions
request.COOKIES同样也是一个字典,代表了存储在请求里的HTTP cookies,一般来说cookies都是用来实现会话即session的特性,会话通常是用来实现状态的,因为http协议本身是没有状态的,每一次请求或者相应都是独立的。有了session之后,web应用就可以在服务端保存用户的数据。在django中,session也是HttpRequest的一个字典类属性。具体表示为request.session
响应对象:
响应的主要数据就是存放在content属性里的正文,一般就是一个巨大的html字符串,对于HttpResponse非常重要,下面是几种常用的操作:
1、创建响应对象,HttpResponse接受一个字符串作为构造函数的参数,并且将他保存子content里面。
response = HttpResponse("<html>Hello World</html>")
这样就实现了一个简单的响应。
2、一点一点构建响应内容
response = HttpResponse()
response.write("<html>")
response.write("Hello world")
response.write("</html>")
3、设置HTTP头,可以把HttpResponse当作一个字典使用
response = HttpResponse()
response["Content-Type"] = "text/csv"
response["Content-Length"] = 256
并且有许多已经定制好的子类:
HttpResponseForbidden(HTTP 403)
HttpResponseServerError(HTTP 500)
中间件:
middlware可以在
1、请求到达视图之前对他进行修改;
2、在响应到达用户之前对响应进行修改;
Django里的中间件组件就是一个Python类,定义了一些名为process_request或是process_view这样的方法。
具体使用到哪些middleware都会在setting.py文件里的MIDDLEWARE_CLASSES元组里列出,django会自动加载上这些类,等到适合的场景就会调用。这些类罗列的顺序会决定他们执行的顺序。
请求中间件:
请求中间件一般定义在输入端,定义为一个实现了process_request方法的类:
from some_exterior_auth)lib import get_user
class ExteriorAuthMiddleware(object):
def process_request(self,request):
token = request.COOKIES.get('auth_token')
if token is None and not request.path.startswith('/login'):
return HttpRequestRedirect('/login/')
request.exterior_user = get_user(token)
代码主要是测试用户是否已经登录的中间件
响应中间件:
响应中间件是运行在视图函数返回的HttpResponse对象之上,这样的中间件必须实现process_response方法,这个方法接受一个request和一个response参数并返回一个HttpResponse或者子类的对象。
常见的用法实在响应里插入额外的头信息。
class TestFilterMiddleware(object):
def process_response(self,request,response):
response.content = response.content.replace('foo','bar')
将web输出的所有文本里的foo 替换成 bar
视图与逻辑:
对视图的唯一要求就是他们必须接受一个HttpRequest对象,并返回一个HttpResponse对象。
通用视图:
django中一些常见的通用视图:
simple.direct_to_template
list_detail.object_list list_detail.object_detail
create_update.create_object create_update.update_object
date_based
自定义视图:
自己编写视图,django提供了一些快捷的方法,大部分都在django.shortcuts里
1、render_to_response :这个函数代替了两步的功能。先创建一个context对象,然后然后用Template进行渲染,最后返回包含结果的HttpResponse。
2、Http404:这个Exception子类会返回一个HTTP404的错误,并且渲染一个404.html的模板。
3、get_object_or_404 和get_list_or_404:
两个函数功能相似,获得一个对象或者列表,如果查找失败就跑出Http404.
手动抛出404异常的例子:
from django.shortcuts import render_to_response
from django.http import Http404
from myproject.myapp.models import Person
def person_detail(request,id):
try:
person = Person.objects.get(pk=id)
except Person.DoesNotExist:
raise Http404
return render_to_response("person/detail.html",{"pserson“:person})
get_object_or_404例子:
from django.shortcuts import render_to_response,get_object_or_404
from myproject.myapp.models import Person
def person_detail(request,id):
person = get_object_or_404(Person,pk=id)
return render_to_response("pserson/detail/html",{"pserson":pserson})