LoginSignup
2
2

More than 5 years have passed since last update.

Djnagoでurlpatternsを記述する際の注意(初心者向け)

Posted at

Djangoのurls.pyは上から順番にURLのパターンマッチを探すので、順番は大事!

ものすごく基本的なことですが、見落としていたことによってだいぶハマってしまったので反省を込めて記録。。。

(※この記事では、「現場で使えるDjango基礎編」(注)で提唱されているベストプラクティスを参考に
新規プロジェクト作成時に、自動で生成されるプロジェクトと同名のフォルダである
mysite/mysitemysite/configに変更しております。
(プロジェクト名がmysiteの場合)
個人的には、このやり方、わかりやすくて非常に良いと思いました。)

ハマったこと

管理サイトからブログ記事と写真をアップロードして、
HTML内で<img src="{{ post.image.url }}" として写真ファイルを呼び出そうとしても表示されない。

image.png

ソースコードを見ると、
image.png

意図通り、mysite/media ディレクトリ(config/settings.pyでMEDIA_ROOTとして指定したディレクトリ)を参照するようになっていますが、/media/haikei2.pngをクリックすると、トップ画面に移動してしまいます。

config.urls.pyを見てみると、


from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include, re_path
from django.conf.urls import url
from django.views.generic import RedirectView
from django.conf import settings


urlpatterns = [
    path('admin/', admin.site.urls),
    path('top/', include('top.urls')),
    path('posts/', include('posts.urls')),
    re_path(r'\w*',  RedirectView.as_view(url='/top/'), name='redirect_to_index')
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

当たり前じゃないか、と思う方も多いかもしれません。
そうです、

urlpatterns += re_path(r'\w*', RedirectView.as_view(url='/top/'), name='redirect_to_index')

このコードは、「ホスト名の後に存在しないパターンが入力された場合(コピペなどした後に何かのはずみで英数字を入れてしまったときなど)でも、トップ画面にリダイレクトしてくれるようにしよう」という意図で書いたものですが、このコードの位置が悪かったです。

この状態では、re_path関数の上のURL、(つまりadmin, top, posts)以外のURLについては、一切合切がRedirectViewの対象となってしまいます。一番下のstatic~が置いてけぼりにされてしまっています。。

なので、このようにしたら、意図通りにmediaディレクト内のファイルを読み込んでくれるようになりました。


from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include, re_path
from django.conf.urls import url
from django.views.generic import RedirectView
from django.conf import settings


urlpatterns = [
    path('admin/', admin.site.urls), 
    path('top/', include('top.urls')),
    path('posts/', include('posts.urls')),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += [re_path(r'\w*',  RedirectView.as_view(url='/top/'), name='redirect_to_index')]

結論: Djangoのurls.pyは上から順番にURLのパターンマッチを探すので、順番は大事!

そもそも、Pythonが
関数やクラスを含む変数を上から読む言語(「インタプリタ言語」と呼ばれる)

ですからね。

(注)https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Django-%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8%E3%80%8A%E5%9F%BA%E7%A4%8E%E7%B7%A8%E3%80%8B-%E6%A8%AA%E7%80%AC-%E6%98%8E%E4%BB%81/dp/4802094744

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2