別のページにオプションのDjangoアプリケーションを埋め込みます(そのアプリケーションが存在する場合)

私たちは複数のサイトにDjangoプロジェクトをインストールしています。 2人では、フロントページに表示されるステータスボックスを生成するアプリもあります。アプリがインストールされた場合、それを表示させる正しい方法は何ですか?アプリが存在しない場合、何も表示されません。

ステータスアプリでメインのインデックスページを拡張することでそれを実現できると思います。

{% extends "mainproject/index.html" %}

{% block statusboxplaceholder %}
<div> status here </div>
{% endblock %}

それは正しい、慣用的なアプローチですか?フロントページ全体をちょうど少しのコンテンツを追加するように拡張するのは、やや直感的ではないようです。

編集:また、自分のアプリケーションが独自の "インデックス"ページを定義したいという事実を管理するにはどうしたらいいですか?それはプロジェクト全体の "インデックス"ページよりも優先されるべきですか?私は明らかに、プロジェクトのurls.pyに参照をハードコードしたくない。その配備にインストールされている特定のアプリケーションを参照する配備固有のurls.pyを作成しますか?もしそうなら、それはINSTALLED_APPSの情報を繰り返すのではなく、したがってDRYに違反していませんか?

1

1 答え

あなたのアプローチには問題はありませんが、一般的なテンプレートタグは、特に後からインストールする可能性のある他のアプリケーションにこの機能を拡張したい場合に、最も柔軟性があります。

ベーステンプレートは一般的な "boxes"タグを読み込みます。タグのソースでは、その特定のインスタンスのインストールされたアプリケーションに基づいて、任意のものをレンダリングできます。したがって、ボックスをレンダリングするための一連のデフォルトのアプリケーションを持つことができます。また、エンドユーザーは、どのアプリケーションにボックスをレンダリングするかをカスタマイズできます。

設定、コンフィグレーション、またはタグ自体でも、アプリケーションごとにブロック用にレンダリングするテンプレートを指定できます。

各アプリケーションが app/templates ディレクトリにテンプレートを持っていると仮定すると、この擬似コードはあなたを動かすはずです(これはテストされていません):

from django.conf import settings
from django import template
register = template.Library()

class GenericBox(template.Node):
   def __init__(self, app):
      self.app = app
   def render(self, context):
      if self.app not in settings.INSTALLED_APPS:
         return '' # if the app is not installed
      # Here you would probably do a lookup against
      # django.settings or some other lookup to find out which
      # template to load based on the app.
      t = template.loader.get_template('some_template.html') # (or load from var)
      c = template.RequestContext(context,{'var':'value'}) # optional
      return t.render(c)    

@register.tag(name='custom_box', takes_context=True, context_class=RequestContext)
def box(parser, token):
    parts = token.split_contents()
    if len(parts) != 2:
        parts[1] = 'default_app' # is the default app that will be rendered.
    return GenericBox(parts[1])
2
追加された