revision-up-to: | 17812 (1.4) |
---|
すっきりした、簡潔で明解な URL スキームの設計は、高品質の Web アプリケーショ ンでは重要な要素です。 Django では、フレームワークの制限なしに、望み通りの URL を設計できます。
.php
や .cgi
といった拡張子は必要なく、 0,2097,1-1-1928,00
のよ
うな意味不明の URL にする必要もありません。
URL はすっきりした扱いやすいものにすべきであるという主張については、ワール ドワイドウェブの産みの親である Tim Berners-Lee の優れた解説、 Cool URIs don’t change を参照してください。
あるアプリケーション向けの URL を設計するには、 URLconf (URL 設定: URL configuration) と呼びならわされている Python モジュールを作成します。このモ ジュールは pure Python のコードで、中にはただ URL パターン (単純な正規表現) から Python のコールバック関数 (自作のビュー) へのマッピングが入っているだ けです。
このマッピングは短くもできますし、必要なだけ長くもできます。他のマッピング も参照できます。また、 pure Python コードなので、動的に生成できます。
ユーザが Django で作られたサイト上のページをリクエストした時に、どの Python コードが実行されるかは以下のアルゴリズムで決定されます:
ROOT_URLCONF
に設定されています。ただし、
HttpRequest
オブジェクトに urlconf
という属性が設定されてい
た場合( request processing で設定されます)
、その値を ROOT_URLCONF
の代わりに使います。urlpatterns
とい
う名前の変数を探します。この変数の値は Python のリストで、
django.conf.urls.patterns()
が返すのと同じ形式です。HttpRequest
が、それ以降の引
数には正規表現でキャプチャした値が渡されます。エラーハンドリング
を見てください。URLconf の一例を示します:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
(r'^articles/2003/$', 'news.views.special_case_2003'),
(r'^articles/(\d{4})/$', 'news.views.year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)
注意:
^/articles
ではなく ^articles
にします。'r'
があります。これは必須ではあり
ませんが、付けた方がよいでしょう。 r
は、”raw” 文字列、すなわち文
字列中のいかなる文字もエスケープしないことを表します。
Dive Into Python’s explanation も参考にしてください。例のリクエストを挙げて説明しましょう:
/articles/2005/03/
へのリクエストは 3 つめのエントリにマッチしま
す。 Django は news.views.month_archive(request, '2005', '03')
を
呼び出します。/articles/2005/3/
はどの UrL パターンにもマッチしません。リストの
3 つめのエントリでは月番号が 2 桁になるよう要求しているからです。/articles/2003/
はリストの 2 番目ではなく、最初のパターンにマッチ
します。パターンは順番に調べられ、最初にテストにパスしたものが使われ
るからです。この法則を、特別扱いしたい URL の処理に使ってもかまいませ
ん。/articles/2003
は URL がスラッシュで終わっていないので、どのパター
ンにもマッチしません。/articles/2003/03/3/
は最後のパターンにマッチします。 Django は
news.views.article_detail(request, '2003', '03', '3')
を呼び出し
ます。上の例では、 名前なしの 簡単な正規表現グループを (丸括弧表記で) 使って URL から情報を取り出し、ビュー関数に 固定引数 として渡していました。より 高度な方法に、 名前つきの 正規表現グループで URL から情報を取り出し、ビュー の キーワード引数 に渡すものがあります。
Python の正規表現では、名前つき正規表現グループは、 name
をグループの名
前、 pattern
をマッチさせるパターンとして、 (?P<name>pattern)
で表
されます。
上の URLconf の例を書き換えて、名前つきグループにしたものを示します:
urlpatterns = patterns('',
(r'^articles/2003/$', 'news.views.special_case_2003'),
(r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$', 'news.views.article_detail'),
)
この URLconf は前の例と全く同じ機能を実現しますが、一つだけはっきり違うのは、 取り出した値を固定引数ではなくキーワード引数としてビュー関数に渡すという点 です。例えば:
/articles/2005/03/
へのリクエストは、
news.views.month_archive(request, year='2005', month='03')
ではなく
news.views.month_archive(request, '2005', '03')
を呼び出します。/articles/2003/03/3/
へのリクエストは
news.views.article_detail(request, year='2003', month='03', day='3')
を呼び出します。実際には、このような名前つきグループを使うと URLconf が少しだけ明示的な書き 方になり、引数の順番に起因するバグを起こしにくくなります – それに、自作ビュー の関数定義で引数順を変更できます。いうまでもなく、こうした恩恵は簡潔さの犠 牲の上に成り立っています: 開発者の中には、名前つきグループの構文が醜くて冗長 だと感じる人もいます。
URLconf パーザが正規表現中の名前つきグループと名前なしグループを扱う際のア ルゴリズムを以下に示します:
名前つきの引数があればそれを使います。名前なし引数は無視します。名前つきの 引数がなければ、すべての名前なし引数を固定引数として使います。
どちらの場合でも、追加のキーワード引数を指定できます。後述の「ビュー関数に 追加のオプションを渡す」を参照してください。
URLconf はリクエストされた URL を通常の Python 文字列として検索します。この 文字列には GET や POST のパラメタも、ドメイン名も入りません。
例えば、 http://www.example.com/myapp/
URLconf が検索対象にするのは
myapp/
です。
http://www.example.com/myapp/?page=3
へのリクエストの場合でも
myapp/
です。
URLconf はリクエストメソッドを調べません。換言すれば、同じ URL に対する
POST
, GET
, HEAD
といった全てのリクエストメソッドは同じビュー関
数に送られます。
urlpatterns
の書き方¶urlpatterns
は django.conf.urls.patterns`()
の返す形式の
Python リストになります。 urlpatterns
変数の値を作るときには、常に
patterns()
を使うようにして下さい。
django.conf.urls
汎用的な関数¶Deprecated since version 1.4: Django 1.4 の関数 patterns
, url
, include
に加えて handler*
は
django.conf.urls
モジュールの中にあり、以下で説明さ
れているシンボル群です。
Django 1.3 までは、これらは django.conf.urls.defaults
の中に位置していました。まだ、以前のモジュールからインポート
することが出来ますが、 Django 1.6 でそれが出来なくなります。
patterns
(prefix, pattern_description, ...)¶プレフィクス (prefix) 引数、および任意の個数の URL パターンをとり、Django で必要な形式の URL パターンのリストを返す関数です。
patterns()
の最初の引数は プレフィクス (prefix)
文字列です。後述の
「 ビュープレフィクス 」 を参照してください。
残りの引数は以下の形式のタプルにします:
(正規表現, Pythonコールバック関数 [, パラメタ辞書 [, エントリ名]])
パラメタ辞書
および エントリ名
はオプションで、省略できます
(詳しくは「 ビュー関数に追加のオプションを渡す 」を参照してください)。
Note
patterns()
は関数呼びだしの形式を取っているので、取れる引数 (URL パ
ターン) は最大 255 個に制限されています。これは全ての Python 関数呼びだ
しに共通する制約です。通常は、 URL パターンを include()
でモジュラ
に構造化するものなので、事実上この制約はほとんど問題になりません。とは
いえ、運悪く 255 個の制約に引っかかってしまうようなら、 pattern()
が Python のリストを返すということを思い出して、以下のように引数を分割
し、リストを構築するとよいでしょう:
urlpatterns = patterns('',
...
)
urlpatterns += patterns('',
...
)
Python のリスト型にはサイズ制限がありませんから、いくつでも URL パター ンを定義できます。ただし、一度に 254 個づつ (先頭のプレフィクス引数のた めに、 255 個のうちの一つを使います) しか定義できないという制約に注意し てください。
url
(regex, view, kwargs=None, name=None, prefix='')¶url()
関数は、タプルの代わりとして patterns()
の引数に指定できます。
この関数は、パラメタ辞書がないときに URLconf のエントリ名を指定したい場合に
便利です。例えば、以下のように用います:
urlpatterns = patterns('',
url(r'/index/$', index_view, name="main-view"),
...
)
この関数は 5 つの引数をとり、そのほとんどが省略可能です:
url(regex, view, kwargs=None, name=None, prefix='')
name
パラメタが便利な理由は「
URL パターンに名前を付ける 」の節を参
照してください。
prefix
パラメタは patterns()
の最初の引数と同じ意味を持ち、
view
を文字列形式で指定する場合にしか使われません。
include
(<module or pattern_list>)¶関数は現在の URLconf で “included” しておくべき Python のフル import パス を他の URLconf モジュールへと 取りこみます。
include()
も引数としてイテレート可能です。これは、
URL パターンを返します。
他の URLconf を取り込む を見てください。
Django が、リクエストされた URL にマッチする正規表現を 見つけられなかったとき、または例外が発生したとき、 Django は error-handling view を発生させます。ビューはルートの URlconf に設定された三つの変数で、指定されたケースで使用 されます。これらの変数の設定は、他のどの URLconf にも影響を 与えません。
エラービューのカスタマイズ を参照してください、もっと詳しいことが載っています。
handler403
¶呼ぶことができます、またはユーザがリソースにアクセスするのに 必要なパーミッション(permission 権限)を持っていない場合に、 ビュー関数への完全な Python の import パスが入った文字列です。
通常、これは 'django.views.defaults.permission_denied'
これのデフォルト値は満足させるでしょう。
403 (閲覧が禁止されています ビュー) にもっと沢山の情報が載っています。
handler403
は Django 1.4の新しいものです引数として取り出したテキストは、正規表現が何にマッチするかに関係なく通常の Python 文字列型になります。例えば、下のような URLconf の行:
(r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
では、 news.views.year_archive()
に渡される year
引数は、整数ではな
くあくまでも文字列になります。 \d{4}
が整数を表す文字列にしかマッチしな
いことは関係ありません。
よく使うトリックとして、ビュー関数の引数にデフォルトパラメタを指定しておく という方法があります。 URLconf とビューの一例をあげて説明しましょう:
# URLconf
urlpatterns = patterns('',
(r'^blog/$', 'blog.views.page'),
(r'^blog/page(?P<num>\d+)/$', 'blog.views.page'),
)
# View (in blog/views.py)
def page(request, num="1"):
# Output the appropriate page of blog entries, according to num.
上の例では、 URL パターンはどちらも同じビュー、 blog.views.page
を指し
ています。しかし、最初のパターンでは、 URL から何の情報も取り出しません。最
初のパターンがマッチすると、 page()
関数は num
の値として、デフォル
トの "1"
を使います。二つめのパターンがマッチすると、 page()
は正規
表現で取り出した num
の値を使います。
urlpatterns
内の各正規表現は、最初にアクセスした際にコンパイルされます。
これによって、システムは劇的に高速になります。
コードを繰り返し書かなくてもよいように、 patterns()
呼び出しの中で共通
のプレフィクスを指定できます。
Django の概要 からとってきた URLconf の例を示します:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
(r'^articles/(\d{4})/$', 'news.views.year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)
この例では、各ビューには共通のプレフィクス、 'news.views'
があり
ます。 urlpatterns
の各エントリに繰り返し入力する代わりに、
patterns()
関数の最初の引数にプレフィクスを指定して、各ビュー関数に適用
できます。
このことを念頭に置いて、上記の例をもっと簡潔に書くと以下のようになります:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('news.views',
(r'^articles/(\d{4})/$', 'year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'article_detail'),
)
プレフィクスには末尾のドット ("."
) を入れていないことに注意してください。
Django はドットを自動的に入れます。
現実的には、色々なビューを取り混ぜて使うことになり、 urlpatterns
に共通
のプレフィクスを持たせられなくなることでしょう。しかし、パターンの重複を防
ぐビュープレフィクスのショートカット機能には、もう一つの利用法があります。
それは、以下のように複数の patterns()
オブジェクトを足し合わせるという
ものです:
古い書き方:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
(r'^$', 'django.views.generic.date_based.archive_index'),
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'django.views.generic.date_based.archive_month'),
(r'^tag/(?P<tag>\w+)/$', 'weblog.views.tag'),
)
は、以下のような書き方に改められます:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('django.views.generic.date_based',
(r'^$', 'archive_index'),
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$','archive_month'),
)
urlpatterns += patterns('weblog.views',
(r'^tag/(?P<tag>\w+)/$', 'tag'),
)
urlpatterns
好きな場所で、他の URLconf モジュール上の定義を取り込めます。
この操作は、本質的には一連の URL を他の URLconf の下に「すげかえる(root)」
操作になります。
例として、 Django ウェブサイト 自体の URLconf の例外を示します。この URLconf は他の URLconf をいくつも取り込んでいます:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
# ... snip ...
(r'^comments/', include('django.contrib.comments.urls')),
(r'^community/', include('django_website.aggregator.urls')),
(r'^contact/', include('django_website.contact.urls')),
(r'^r/', include('django.conf.urls.shortcut')),
# ... snip ...
)
この例の正規表現が、 $
(行末にマッチする文字) を使っておらず、末尾にスラッ
シュを付けていることに注意しましょう。 Django が include()
をみつけると、
URL からマッチした部分を取り去り、残りの文字列を include された URLconf に
送って続きの処理を行わせます。
URLconf を Python モジュールで include 引数で指定する方法ではなく、 追加した URL patterns を含める別の可能性として、 patterns によって 返されたパターンリストを直接的に使う方法があります。:
from django.conf.urls import patterns, url, include
extra_patterns = patterns('',
url(r'^reports/(?P<id>\d+)/$', 'credit.views.report', name='credit-reports'),
url(r'^charge/$', 'credit.views.charge', name='credit-charge'),
)
urlpatterns = patterns('',
url(r'^$', 'apps.main.views.homepage', name='site-homepage'),
(r'^help/', include('apps.help.urls')),
(r'^credit/', include(extra_patterns)),
)
この手法は、 Django のアドミンアプリケーションのインスタンスを配置する時に
見られます。 Django のアドミンは、
AdminSite
のインスタンスとして
配置されます。それぞれの ~django.contrib.admin.AdminSite
インスタンスは urls
アトリビュートを持っていて、
それらは url パターンとしてインスタンスに使用可能です。
それは、アドミンのインターフェイスを配置する時に、 include()
を
プロジェクトの urlpatterns
に入れることができます。
include された側の URLconf は、親となる URLconf で取り出された全てのパラメ タを受け継ぎます。従って、以下のような例はうまく動作します:
# In settings/urls/main.py
urlpatterns = patterns('',
(r'^(?P<username>\w+)/blog/', include('foo.urls.blog')),
)
# In foo/urls/blog.py
urlpatterns = patterns('foo.views',
(r'^$', 'blog.index'),
(r'^archive/$', 'blog.archive'),
)
上の例では、 include された側にも "username"
変数が期待どおりに渡されま
す。
もし、複数のインスタンスを一つのアプリケーションで必要としたならば、 インスタンスの間で区別を付けられることが役立つでしょう。 これは、一つのアプリケーションが分割する URL の名前付けの 複数のインスタンスにおいて URL の名前付け を使う時に 特に大切になります。一つのアプリケーションの中の複数の インスタンスは、名前づけられた URL を分割します、名前空間は インスタンスそれぞれに名前づけられた URL の分割を教える方法です。
URL の名前空間は二つのパートになります、両方とも文字列です:
admin
です。admin
の
インスタンスの名前空間を持っています。URL の名前空間は二つの方法によって指定されています。
始めに、URL パターンを構成する時、アプリケーションとインスタンスの名前空間を、
include()
の引数として、渡すことができます。:
(r'^help/', include('apps.help.urls', namespace='foo', app_name='bar'))
これは apps.help.urls
のなかで定義された URL を含み、インスタンスの
名前空間 bar
と、アプリケーションの名前空間 foo
へといきます。
二つ目は、埋め込まれた名前空間のデータを内包するオブジェクトを含むことができま
す。もし、 patterns
オブジェクトを include()
したなら、オブジェクトは
グローバルな名前空間へと加えられます。しかしながら、三つのタプルを
含んだオブジェクトを include()
することもできます:
(<patterns object>, <application namespace>, <instance namespace>)
これは、与えられたアプリケーションとインスタンスの名前空間へと指定された
URL パターンを含みます。例えば、 Django の AdminSite
オブジェクトの
urls
アトリビュートは 3つのタプルを返し、それはアドミンサイトの
全てのパターンを含んでいます。そして、アドミンインスタンスの名前を足すと
アプリケーション名前空間の admin
です。
一度定義した、名前空間化された URL は、名前空間から逆引きしてたどること が出来ます。もっと詳しく、名前空間づけた URL を逆引きする方法について知るには、 URL 名前空間 を見てください。
URLconf には、ビュー関数に追加の引数を Python の辞書型で渡せるようにするた めのフックがあります。
URLconf タプルにはオプションとして 3 つめの要素を指定できます。この要素は ビューに渡したい追加の引数からなる辞書にします。
例えば:
urlpatterns = patterns('blog.views',
(r'^blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
)
この例では、 /blog/2005/
というリクエストに対し、 Django は
blog.views.year_archive()
ビューを呼び出し、以下のキーワード引数を渡し
ます:
year='2005', foo='bar'
このテクニックは 汎用ビュー や 配信フィードフレームワーク で、メタデータ やビューへのオプションを渡すために使われています。
衝突を避ける
URLconf を書くとき、名前付きのキーワード引数をキャプチャさせ、同時に追 加引数の辞書に同名の項目を追加するような書き方ができてしまいます。この 場合、辞書に設定した内容が優先されます。
include()
に追加のオプションを渡す¶include()
にも追加のオプションを渡せます。 include()
に追加のオプショ
ンを渡すと、そのオプションは include された側の URLconf の
全ての URL 設定 に適用されます。
例えば、以下の二つの URLconf は機能的に全く同じです:
その 1:
# main.py: include する側
urlpatterns = patterns('',
(r'^blog/', include('inner'), {'blogid': 3}),
)
# inner.py: include される側
urlpatterns = patterns('',
(r'^archive/$', 'mysite.views.archive'),
(r'^about/$', 'mysite.views.about'),
)
その 2:
# main.py: include する側
urlpatterns = patterns('',
(r'^blog/', include('inner')),
)
# inner.py: include される側
urlpatterns = patterns('',
(r'^archive/$', 'mysite.views.archive', {'blogid': 3}),
(r'^about/$', 'mysite.views.about', {'blogid': 3}),
)
追加オプションは、ビューがオプションを実際に有効なオプションとして受け取る かどうかに関わらず、 常に include される側の URLconf の 全ての 行に渡さ れるので注意してください。このため、 include に追加オプションを渡すテクニッ クが有効なのは、include される側の URLconf に入っている全てのビューが、追加 のオプションを受け取れるとはっきりしている場合だけです。
開発者の中には、ビューのパスが入った文字列の代わりに、ビューそのものを表す Python 関数オブジェクトを渡す方が自然だと考えている者もいます。この代替案も サポートされており、任意の呼び出し可能オブジェクトをビューに渡せます。
例えば、 以下のような「文字列の」URLconf があったとします:
urlpatterns = patterns('',
(r'^archive/$', 'mysite.views.archive'),
(r'^about/$', 'mysite.views.about'),
(r'^contact/$', 'mysite.views.contact'),
)
文字列の代わりにオブジェクトを渡して、同じ機能の URLconf を実現できます。オ ブジェクトを忘れず import してください:
from mysite.views import archive, about, contact
urlpatterns = patterns('',
(r'^archive/$', archive),
(r'^about/$', about),
(r'^contact/$', contact),
)
以下の例も機能的に全く同じです。個々のビューを個別に import する代わりにビュー の入ったモジュールを import すると、すこしだけすっきり書けます:
from mysite import views
urlpatterns = patterns('',
(r'^archive/$', views.archive),
(r'^about/$', views.about),
(r'^contact/$', views.contact),
)
どのスタイルを使うかは自由です。
このテクニックを使った場合 (文字列の代わりにオブジェクトを渡した場合) 上で説明した “”ビュープレフィクス”” は効果を及ぼさないので注意してください。
URLconf 中の複数の URL パターンから同じビュー関数を呼ぶケースはよくあります。
たとえば、以下の二つの URL パターンは、どちらも archive
というビューを
指しています:
urlpatterns = patterns('',
(r'/archive/(\d{4})/$', archive),
(r'/archive-summary/(\d{4})/$', archive, {'summary': True}),
)
この URLconf には何ら問題はないのですが、 (permalink()
デコレータや
{% url %}
を使って) 逆引き URL マッチング (reverse URL matching) を
行うと問題を引き起こします。というのも、二つの URLパターンが同じビューを指
しているために、Django の逆引き URL マッチング機構は、 archive
ビューに
対する正しい URL がわからなくなってしまうからです。
この問題を解決するために、Django は 名前付き URL パターン をサポートし ています。すなわち、各 URL パターンに名前をつけて、同じビューやパラメタを使っ ているパターンどうしを区別できます。その上で、付けた名前を使って逆引き URL マッチングを行えます。
例えば、 URLconf が以下のようになっていたとしましょう:
urlpatterns = patterns('',
url(r'/archive/(\d{4})/$', archive, name="full-archive"),
url(r'/archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"),
)
上記に記した名前(full-archive
and arch-summary
)を使って、個別にそれ
ぞれのパターンの URL にアクセスすることができます。
{% url arch-summary 1945 %}
{% url full-archive 2007 %}
つまり、二つの URL パターンがどちらも同じく archive
ビューを参照してい
ても、 url()
に name
パラメタを指定すれば、テンプレート中で二つを区
別できるというわけです。
URLconf エントリに付ける名前は、どんな文字を入れても構いません。 Python の 変数名規則には縛られません。
Note
URLconf エントリに名前を付ける場合、他のアプリケーションの名前と衝突し なさそうな名前を使ってください。例えば、ある URL パターンを “comment” と命名していて、他のアプリケーションでも同じ名前を使っていたとしましょ う。この名前をテンプレートで使うと、もはやどちらの URL がテンプレートに 挿入されるのか判断する術はありません。
URLconf エントリの名前に、例えばアプリケーション名などからとったプレフィ クスを追加しておけば、名前が衝突しにくくなってよいでしょう。というわけ で、単に “comment” ではなく、 “myapp-comment” にするよう勧めます。
名前空間化された URL は :
演算子を使うことによって指定されます。
例えば、アドミンアプリケーションの、メインのインデックスページは
admin:index
を使うことによって参照されます。
名前空間は、ネスト(nest 入れ子)することができます。 foo:bar:whiz
と名前づけられた URL は、トップレベルの名前空間である foo
の中から
bar
という名前で定義されたものを探し、さらにその中から whiz
という名前のパターンを探します。
名前空間化された URL (すなわち、myapp:index
のようなもの) が与えられる
て解決すると、 Django は完全にパス化されたものをパーツごとに分解しようとしま
す。そしてその時に、 URL の探索を行おうとします。
最初に、 Django はアプリケーションの名前空間とマッチするものを探そうとし
ます。(この例では myapp
です。)これは、アプリケーションのインスタンスの
リストを作ります。
もし、 現在の アプリケーションが定義されていれば、 Django は
インスタンスの為に URL リゾルバを見つけて返します。 現在の アプリケーション
は、テンプレートコンテキストの上のアトリビュートとして指定されます。
アプリケーションは複数の配置を持つことを想定していて、テンプレートのレンダ
リングをするために使われる Context
か RequestContext
の
current_app
アトリビュートに指定されます。
現在のアプリケーションは reverse()
関数の引数から、手動で
指定することも出来ます。
もし、現在のアプリケーションがないとしたらどうでしょう。 Django は
デフォルトのアプリケーションインスタンスを探します。デフォルトの
アプリケーションインスタンスは、アプリケーションの名前空間とマッチする
インスタンスの名前空間を持つインスタンスです。(この例では、
myapp
のインスタンスは myapp
と呼ばれます)
もし、デフォルトのアプリケーションインスタンスがなかったとしたら、 Django は一番初めに配置されたアプリケーションのインスタンスを選択します。 それは、インスタンスの名前がどんなものであってもそうでしょう。
もし、提供された名前空間がステップの1のアプリケーションの名前空間と マッチしない場合、 Djangoはインスタンスの名前空間として、直接参照しようと します。
もし入れ子になった名前空間なら、ビューの名前が逆引きできるまで、名前空間の それぞれのパートに対してこれらのステップを繰り返します。
この行動の解決戦略をお見せしましょう、 myapp
: の foo
と呼ばれる
インスタンスと、 bar
と呼ばれるものについて考えてみましょう。
myapp
はメインのインデックスページを持っていて、 URL の名前は index で
す。セットアップを使って、参照可能にしてみましょう。:
bar
インスタンスの中でユーティリティページをレンダリングしならば、
myapp:index
は、 bar
インスタンスのインデックスページとして
逆引きします。myapp:index
は最後に登録された
myapp
のインスタンスを逆引きします。これらは通常のインスタンスではなく、
myapp
の最後のインスタンスが使われます。これは foo
か bar
で、プロジェクトの URL パターンに導入された順番に依存します。foo:index
は常に foo
インスタンスのインデックスページを解決しようと
します。もし、通常のインスタンスも存在すれば、すなわち、 myapp と名前づけられた インスタンスが存在すると、このようなことがおきます。:
bar
インスタンスの中でユーティリティページをレンダリングしならば、
myapp:index
は、 bar
インスタンスのインデックスページとして
逆引きします。myapp:index
は、通常のインスタンスの
インデックスページとして逆引きします。foo:index
は、再び foo
インスタンスのインデックスページへと
逆引きします。django.core.urlresolvers
ユーティリティ関数¶コード中で url
のようなことをしたい場合のために、Django では
django.core.urlresolvers.reverse
モジュールを提供しています:
reverse
(viewname[, urlconf=None, args=None, kwargs=None, current_app=None])¶viewname
は関数名 (関数への参照か、関数名の文字列表記で、
urlpatterns
上で使っている形式) または
URL パターン名 です。通常、
urlconf
パラメタについて考える必要はなく、以下のように、固定引数とキー
ワード引数だけを指定して url マッチングを行います:
from django.core.urlresolvers import reverse
def myview(request):
return HttpResponseRedirect(reverse('arch-summary', args=[1945]))
reverse()
関数は大抵の正規表現パターンを URL に逆変換できますが、全てと
は限りません。今のところ、パターン中に垂直バー ("|"
) を含められません。
垂直バーを含むパターンは、 URL からビューへのマッチングには問題なく使えます
が、パターンの逆変換はできないので注意してください。
current_app
引数は、リゾルバが現在実行しているるビューが属している
アプリケーションを指し示すためのヒントを提供します。この current_app
引数は、アプリケーションの名前空間をひも解き、指定したアプリケーション
インスタンスへと導くヒントとして扱われ、
URL 名前空間
に従っています。
args
の代わりに、 kwargs
を用いることもできます。例えば:
>>> reverse('admin:app_list', kwargs={'app_label': 'auth'})
'/admin/auth/'
args
と kwargs
は、 reverse()
を同時に通過することはできません。
ビューが全て正しいことを確認してください
URL 名の種々のパターンへのひも付けの生成の一部として、
reverse()
関数は、 URLconf ファイルのすべてと調べる各ビューの名前
をインポートする必要があります。これは各ビュー関数のインポートと関連
しています。もし 何か エラーが、ビュー関数のインポートする中で起きれば
、それは reverse()
がエラーを返す原因になります。もし、ビュー関数が
逆引きしようとしたものでなかったときでさえもです。
URLconf ファイルの中でビューの参照が実在するのと、 正しくインポートされていることを確かにしてください。 参照するビューがまだ書かれていないのに、それを行に含まないでください。 なぜならそのビューはまだインポートできないからです。
リリースノートを参照してください
reverse() の簡単に使えるバージョン
reverse_lazy
(viewname[, urlconf=None, args=None, kwargs=None, current_app=None])¶これは、プロジェクトの URLConf がロードされる前に、 URL 逆引きを使う必要がある 場合に便利です。いくつかの一般的なケースではこの関数がまさに必要になります:
url
アトリビュートとして、
URL を逆引きして提供する場合django.contrib.auth.decorators.permission_required()
の
デコレータのための login_url
引数のような)django.core.urlresolvers.resolve()
関数は、URL のパスとそれに付随してい
るビュー関数を呼び出すのに使われます。
resolve
(path, urlconf=None)¶path
はあなたがひも解きたい URL パスです。
reverse()
と一緒で、 urlconf
パラメータ
に関して考える必要はありません。この関数が返すのは ResolverMatch
オブジェクトで、これは解決された URL の様々なメタデータにアクセスできる
クラスです。
もし、 URL がひも解かれなかったら、関数は Http404
という例外を発生させます。
ResolverMatch
¶func
¶URL を提供するのに使われるビュー関数です。
args
¶これは、ビュー関数に渡されて、 URL からパースされた 引数です。
kwargs
¶このキーワード引数はビュー関数に渡され、 URL からパースされた 引数です。
url_name
¶URL にマッチした URL パターンの名前です。
app_name
¶アプリケーションの名前空間で、 URL にマッチした URL パターンの 為に使われます。
namespace
¶インスタンスの名前空間で、 URL にマッチした URL パターンの 為に使われます。
namespaces
¶インスタンスのフルの名前空間の、個別の名前空間の要素を
リストにしたもので、 URL パターンにマッチした URL のために
用いられます。すなわち、もし名前空間が foo:bar
であるなら、
このリストは ['foo', 'bar']
になります。
ResolverMatch
オブジェクトは、 URL にマッチする URL パターンに
ついての情報を提供し、それの問い合わせを行うことが出来ます。:
# Resolve a URL
match = resolve('/some/path/')
# Print the URL pattern that matches the URL
print match.url_name
ResolverMatch
オブジェクトは、三つのものに対して割当てられます。:
func, args, kwargs = resolve('/some/path/')
resolve()
は Django 1.3 では、
三つのものを含んで(ビュー関数と、引数、キーワード引数)いて、
ResolverMatch
object (名前空間とパターン情報の提供も同じように)
は DJango の前バージョンのものでは使えません。一つの resolve()
の使い方としては、
Http404
エラーが出ているかどうかを、リダイレクトする前にテストする
ような用途です。:
from urlparse import urlparse
from django.core.urlresolvers import resolve
from django.http import HttpResponseRedirect, Http404
def myview(request):
next = request.META.get('HTTP_REFERER', None) or '/'
response = HttpResponseRedirect(next)
#リクエストとレスポンスを必要に合わせて変更してください。
#依存するローカルな環境のクッキーもセットしてください。
view, args, kwargs = resolve(urlparse(next)[2])
kwargs['request'] = request
try:
view(*args, **kwargs)
except Http404:
return HttpResponseRedirect('/')
return response
django.db.models.permalink()
は、モデルの get_absolute_url()
メソッ
ドのような、完全な URL パスを返す短いメソッドを書く際に便利なデコレータです。
詳細は、 django.db.models.permalink()
を参照してください。
get_script_prefix
()¶通常、 reverse()
を
使うか、 permalink()
を URL を
アプリケーション内で定義するために用います。しかし、もしアプリケーションが
自身の URL の階層の一部分を構成するのならば、 URL を生成する機会が必要です。
このようなケースで、 Web サーバー内の Django プロジェクトの ベース URL を
見つけられる必要があり(通常、 reverse()
がこのような必要性を満たしてくれます)、この場合、 get_script_prefix()
を呼ぶと、Django プロジェクトにへ URL スクリプトのプレフィクスを返します。
もし、 Django プロジェクトが Web サーバーのルートに存在するなら、
これは常に "/"
になります、しかしこれは変更可能です、
django.root
を使うことでインスタンスで出来ます。(
Django と Apache と mod_python
を見てください。)
Oct 26, 2017