Django 简明教程

Django - URL Mapping

现在,我们有了上一章中解释的一个正在工作的视图。我们希望通过一个 URL 访问该视图。Django 有自己的 URL 映射方式,这是通过编辑项目 (myproject/url.py) 文件完成的。url.py 文件类似于 -

Now that we have a working view as explained in the previous chapters. We want to access that view via a URL. Django has his own way for URL mapping and it’s done by editing your project url.py file (myproject/url.py). The url.py file looks like −

from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
   #Examples
   #url(r'^$', 'myproject.view.home', name = 'home'),
   #url(r'^blog/', include('blog.urls')),

   url(r'^admin', include(admin.site.urls)),
)

当用户对 Web 应用程序上的页面发出请求时,Django 控制器接管,通过 url.py 文件查找相应的视图,然后返回 HTML 响应或 404 未找到错误(如果未找到)。在 url.py 中,最重要的事情是 "urlpatterns" 元组。它定义了 URL 和视图之间的映射关系。映射是 URL 模式中的元组,如下所示 -

When a user makes a request for a page on your web app, Django controller takes over to look for the corresponding view via the url.py file, and then return the HTML response or a 404 not found error, if not found. In url.py, the most important thing is the "urlpatterns" tuple. It’s where you define the mapping between URLs and views. A mapping is a tuple in URL patterns like −

from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
   #Examples
   #url(r'^$', 'myproject.view.home', name = 'home'),
   #url(r'^blog/', include('blog.urls')),

   url(r'^admin', include(admin.site.urls)),
   url(r'^hello/', 'myapp.views.hello', name = 'hello'),
)

标记的行将 URL“/ home”映射到在 myapp/view.py 文件中创建的 hello 视图。正如您在上面看到的那样,一个映射由三个元素组成 -

The marked line maps the URL "/home" to the hello view created in myapp/view.py file. As you can see above a mapping is composed of three elements −

  1. The pattern − A regexp matching the URL you want to be resolved and map. Everything that can work with the python 're' module is eligible for the pattern (useful when you want to pass parameters via url).

  2. The python path to the view − Same as when you are importing a module.

  3. The name − In order to perform URL reversing, you’ll need to use named URL patterns as done in the examples above. Once done, just start the server to access your view via :http://127.0.0.1/hello

Organizing Your URLs

到目前为止,我们已在“myprojects/url.py”文件中创建了 URL,但是如前所述,关于 Django 和创建应用程序,最好的办法是能够在不同的项目中重复使用应用程序。如果您将所有 URL 都保存在“projecturl.py”文件中,您可以轻松地了解问题所在。因此,最佳做法是为每个应用程序创建一个“url.py”,并将其包含在我们的主项目 url.py 文件中(我们之前已包含管理界面用的管理 URL)。

So far, we have created the URLs in “myprojects/url.py” file, however as stated earlier about Django and creating an app, the best point was to be able to reuse applications in different projects. You can easily see what the problem is, if you are saving all your URLs in the “projecturl.py” file. So best practice is to create an “url.py” per application and to include it in our main projects url.py file (we included admin URLs for admin interface before).

organize urls

How is it Done?

我们需要使用以下代码在 myapp 中创建一个 url.py 文件 -

We need to create an url.py file in myapp using the following code −

from django.conf.urls import patterns, include, url

urlpatterns = patterns('', url(r'^hello/', 'myapp.views.hello', name = 'hello'),)

然后 myproject/url.py 将更改为以下内容 -

Then myproject/url.py will change to the following −

from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
   #Examples
   #url(r'^$', 'myproject.view.home', name = 'home'),
   #url(r'^blog/', include('blog.urls')),

   url(r'^admin', include(admin.site.urls)),
   url(r'^myapp/', include('myapp.urls')),
)

我们已包含 myapp 应用程序中的所有 URL。通过“/ hello”访问的 home.html 现在为“/ myapp/hello”,这是一个更好、更易于理解的 Web 应用程序结构。

We have included all URLs from myapp application. The home.html that was accessed through “/hello” is now “/myapp/hello” which is a better and more understandable structure for the web app.

myproject

现在,假设我们在 myapp 中有另一个视图“morning”,并且我们希望在 myapp/url.py 中映射它,那么我们将更改我们的 myapp/url.py 为 -

Now let’s imagine we have another view in myapp “morning” and we want to map it in myapp/url.py, we will then change our myapp/url.py to −

from django.conf.urls import patterns, include, url

urlpatterns = patterns('',
   url(r'^hello/', 'myapp.views.hello', name = 'hello'),
   url(r'^morning/', 'myapp.views.morning', name = 'morning'),
)

可以将其重新编排为 -

This can be re-factored to −

from django.conf.urls import patterns, include, url

urlpatterns = patterns('myapp.views',
   url(r'^hello/', 'hello', name = 'hello'),
   url(r'^morning/', 'morning', name = 'morning'),)

如您所见,我们现在使用 urlpatterns 元组的第一个元素。当您想更改应用程序名称时,这可能很有用。

As you can see, we now use the first element of our urlpatterns tuple. This can be useful when you want to change your app name.

urlpatterns

Sending Parameters to Views

我们现在知道如何映射 URL,如何组织它们,现在让我们看看如何向视图发送参数。一个经典示例是文章示例(您想通过“/ articles/article_id”访问文章)。

We now know how to map URL, how to organize them, now let us see how to send parameters to views. A classic sample is the article example (you want to access an article via “/articles/article_id”).

通过在 URL 模式中使用 regexp 捕获参数来传递参数。如果我们在“myapp/view.py”中有一个像下面的视图

Passing parameters is done by capturing them with the regexp in the URL pattern. If we have a view like the following one in “myapp/view.py”

from django.shortcuts import render
from django.http import HttpResponse

def hello(request):
   return render(request, "hello.html", {})

def viewArticle(request, articleId):
   text = "Displaying article Number : %s"%articleId
   return HttpResponse(text)

我们在 myapp/url.py 中进行映射,以便能够通过 “/myapp/article/articleId” 访问它,我们需要在 “myapp/url.py” 中添加以下内容 -

We want to map it in myapp/url.py so we can access it via “/myapp/article/articleId”, we need the following in “myapp/url.py” −

from django.conf.urls import patterns, include, url

urlpatterns = patterns('myapp.views',
   url(r'^hello/', 'hello', name = 'hello'),
   url(r'^morning/', 'morning', name = 'morning'),
   url(r'^article/(\d+)/', 'viewArticle', name = 'article'),)

当 Django 看见 URL: “/myapp/article/42” 时,它将参数 '42' 传递给 viewArticle 视图,你应该在浏览器中看到以下结果 -

When Django will see the url: “/myapp/article/42” it will pass the parameters '42' to the viewArticle view, and in your browser you should get the following result −

passing parameters to viewarticle

请注意,此处参数的顺序很重要。假设我们想要某个月某年的文章列表,让我们添加一个 viewArticles 视图。我们的 view.py 将变成 -

Note that the order of parameters is important here. Suppose we want the list of articles of a month of a year, let’s add a viewArticles view. Our view.py becomes −

from django.shortcuts import render
from django.http import HttpResponse

def hello(request):
   return render(request, "hello.html", {})

def viewArticle(request, articleId):
   text = "Displaying article Number : %s"%articleId
   return HttpResponse(text)

def viewArticle(request, month, year):
   text = "Displaying articles of : %s/%s"%(year, month)
   return HttpResponse(text)

相应的 url.py 文件将如下所示 -

The corresponding url.py file will look like −

from django.conf.urls import patterns, include, url

urlpatterns = patterns('myapp.views',
   url(r'^hello/', 'hello', name = 'hello'),
   url(r'^morning/', 'morning', name = 'morning'),
   url(r'^article/(\d+)/', 'viewArticle', name = 'article'),
   url(r'^articles/(\d{2})/(\d{4})', 'viewArticles', name = 'articles'),)

现在,当你访问 “/myapp/articles/12/2006/” 时,你会得到 'Displaying articles of: 2006/12',但如果你颠倒了参数的顺序,你将无法得到相同的结果。

Now when you go to “/myapp/articles/12/2006/” you will get 'Displaying articles of: 2006/12' but if you reverse the parameters you won’t get the same result.

displaying articles

为了避免这种情况,可以将一个 URL 参数链接到视图参数。为此,我们的 url.py 将变成 -

To avoid that, it is possible to link a URL parameter to the view parameter. For that, our url.py will become −

from django.conf.urls import patterns, include, url

urlpatterns = patterns('myapp.views',
   url(r'^hello/', 'hello', name = 'hello'),
   url(r'^morning/', 'morning', name = 'morning'),
   url(r'^article/(\d+)/', 'viewArticle', name = 'article'),
   url(r'^articles/(?P\d{2})/(?P\d{4})', 'viewArticles', name = 'articles'),)