Django如何处理一个请求:
URL解释:
url 的结构:
schema://host[:port#]/path/.../[?query-string][#anchor]
下面我们看看url在django中最基础的用法:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', views.ArticlesYear.as_view()), #普通用法
url(r'^articles/([0-9]{4})/$', views.ArticlesMonth.as_view()), # 单个非命名参数
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.ArticlesActive.as_view()),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.ArticlesAll.as_view()),
]
注:
命名组
上面的示例使用简单的、没有命名的正则表达式组(通过圆括号)来捕获URL 中的值并以位置 参数传递给视图。在更高级的用法中,可以使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。
在Python 正则表达式中,命名正则表达式组的语法是(?P< name >pattern),其中name 是组的名称,pattern 是要匹配的模式。
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', views.ArticlesYear.as_view()),
url(r'^articles/(?P[0-9]{4})/$' , views.ArticlesMonth.as_view() ),
url(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/$' , views.ArticlesActive.as_view()),
url(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/(?P[0-9]{2})/$' , views.ArticlesAll.as_view()),
]
匹配/分组算法:
指定视图参数的默认值
# URLconf
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^blog/$', views.Page.as_view()),
url(r'^blog/page/(?P[0-9]+)/$' , views.Page.as_view()),
]
# View (in blog/views.py)
class Page(View):
def get(self, request, num="1"):
# Output the appropriate page of blog entries, according to num.
...
错误处理
http常见状态码:
每一个请求,都会返回一个状态
包含其它的URLconfs
在任何时候,你的urlpatterns 都可以包含其它URLconf 模块。这实际上将一部分URL 放置于其它URL 下面。
from django.conf.urls import include, url
urlpatterns = [
# ... snip ...
url(r'^community/', include('django_website.aggregator.urls')),
url(r'^contact/', include('django_website.contact.urls')),
# ... snip ...
]
url匹配时,在项目的urls.py下先进行匹配,然后再匹配对应的include中的URLconf 模块。
在使用Django 项目时,一个常见的需求是获得URL 的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。
人们强烈希望不要硬编码这些URL(费力、不可扩展且容易产生错误)或者设计一种与URLconf 毫不相关的专门的URL 生成机制,因为这样容易导致一定程度上产生过期的URL。
换句话讲,需要的是一个DRY 机制。除了其它优点,它还允许设计的URL 可以自动更新而不用遍历项目的源代码来搜索并替换过期的URL。
要获取一个URL,最初拥有的信息是负责处理它的视图的标识(例如名字),与查找正确的URL 的其它必要的信息如视图参数的类型(位置参数、关键字参数)和值。
Django 提供了一个解决方案使得URL 映射是URL 设计唯一的储存库。你用你的URLconf填充它,然后可以双向使用它:
在需要URL 的地方,对于不同层级,Django 提供不同的工具用于URL 反查
例如:
from django.conf.urls import url
from . import views
urlpatterns = [
#...
url(r'^articles/([0-9]{4})/$', views.Page.as_view() , name='news-year-archive'),
#...
]
在模版中使用:
<a href="{% url 'news-year-archive' 2012 %}">2012 Archivea>
<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archivea>li>
{% endfor %}
ul>
在python代码中使用:
from django.shortcuts import reverse, redirect
from django.views import View
class Page(View)
def get(request):
# ...
year = 2006
# ...
return redirect(reverse('news-year-archive', args=(year,)))
URL 模式的命名
URL 命名空间
URL 命名空间允许你反查到唯一的命名URL 模式,即使不同的应用使用相同的URL 名称。第三方应用始终使用带命名空间的URL 是一个很好的实践。类似地,它还允许你在一个应用有多个实例部署的情况下反查URL。换句话讲,因为一个应用的多个实例共享相同的命名URL,命名空间提供了一种区分这些命名URL 的方法。
一个URL命名空间有两个部分,它们都是字符串:
反查带命名空间的URL
当解析一个带命名空间的URL(例如’polls:index’)时,Django 将切分名称为多个部分,然后按下面的步骤查找:
例如:
假设我们现在有以下两个配置
# urls.py
from django.conf.urls import include, url
urlpatterns = [
url(r'^author-polls/', include('polls.urls', namespace='author-polls', app_name='polls')),
url(r'^publisher-polls/', include('polls.urls', namespace='publisher-polls', app_name='polls')),
]
# polls
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P\d+)/$' , views.DetailView.as_view(), name='detail'),
...
]
根据以上设置,可以使用下面的查询:
如果其中一个实例是当前实例 —— 如果我们正在渲染’author-polls’ 实例的detail 页面 —— ‘polls:index’将解析成’author-polls’ 实例的主页面;例如下面两个都将解析成”/author-polls/”。
reverse('polls:index',current_app=self.request.resolver_match.namespace)
和在模板中:
{% url 'polls:index' %}