自動化無しに生活無し

WEBとかAIとかLinux関係をひたすら書く備忘録系ブログ

【Django】各アプリのトップページとアプリ名をまとめてレンダリングする【apps.pyとurls.pyを操作】

thumbnail

1つのDjangoプロジェクトに複数のアプリを作り、各アプリのリンクをまとめて表示する。

新しいアプリが追加されるたび、そのリンクをテンプレートにて手動で追記しているようではとても手間だ。整合性も取れなくなるだろう。

だから、全てのアプリのトップページのリンクと、アプリ名をまとめて生成。contextに入れ、レンダリングする。

そういう処理を作る。

前提

このコードを実装する前に、以下前提を守る必要がある。

  • 各アプリのurls.pyのapp_nameに、apps.pyのnameと同じ値を与えておく。
  • 各アプリのurls.pyにて、トップページのnameにはindexを指定しておく。
  • 各アプリのapps.pyにverbose_nameを指定している。

構造

下記図のようにhomeアプリから、全てのアプリに遷移できるようにする。

homeアプリは、各アプリのURLを自動的に取れるようにしておくのが今回の目的。

views.py

各アプリの名前を取り出すため、apps.pyを呼び出す。

apps.pyのname と urls.pyのapp_nameの一致を利用して、reverse。

リンクと名前の辞書型を、リストにアペンド。URLとアプリ名をレンダリングする。

from django.shortcuts import render
from django.views import View

from django.apps import apps
from django.urls import reverse

class IndexView(View):
    def get(self, request, *args, **kwargs):

        context = {}

        # 全てのアプリのapps.pyを呼び出す。
        apps_configs    = apps.get_app_configs()

        links   = []
        for apps_config in apps_configs:
            # name="index"があることを前提として実行しているので、念の為にtry文で実行する。
            try:
                dic             = {}

                # TIPS: ここで reverse_lazy() だと、try文が終わった後に例外(存在しないURL名)が発動してしまう。
                dic["url"]      = reverse(f"{apps_config.name}:index")
                dic["name"]     = apps_config.verbose_name

                links.append(dic)
            except:
                continue

        context["links"]    = links

        return render(request, "home/index.html", context)

index   = IndexView.as_view()

重要なのは、URL逆引きのセオリーであるreverse_lazyではなく、reverseを使うこと。

reverse_lazyだと、その逆引き(解決)が実行されるのはtry文を抜けた後。

存在しないURL名を指定してしまったとき、try文の外で例外が発生してしまう。

故に、今回はreverseを使用した。

apps.pyとurls.py

冒頭の前提を守ったコードがこちら。

例えば、homeアプリであれば、apps.pyはこちら。

from django.apps import AppConfig


class HomeConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'home'

    verbose_name = "エントランス"

続いて、urls.pyはこうなる。

from django.urls import path
from . import views

app_name    = "home"
urlpatterns = [
    path("", views.index, name="index"),
]

動かすとこうなる。

homeアプリの名前とリンクが表示されている。

出雲はサーバーの名前、FinanceManagerは別のアプリ。

結論

プライベート用のWEBアプリをいくらか作ることがあるので作った。

社内ポータルサイト作る際にも有効かと思われる。

スポンサーリンク

シェアボタン

Twitter LINEで送る Facebook はてなブログ