私は、Django を使用して、チーム用のプロジェクト管理 Web サイトを作成しています。私の基本テンプレートには、すべてのプロジェクトとユーザーのリストを含むサイドバー メニューが含まれており、DetailView
それぞれそのユーザーまたはプロジェクトの にリンクしています。
私の問題は、サイドバーをレンダリングできるように、すべてのビューにモデルUser
とモデルを提供する必要があることです。Project
追加のコンテキストを追加する; 問題は、各レベルでコンテキストを変更することで DRY に違反しているように感じることです。すべての子クラス(、など) に変更されたコンテキストが含まれるTemplateClass
ように、ベースを単純に再定義することは可能ですか?ListView
DetailView
関連して、これがプロジェクトを設定するためのひどい方法である場合は、そのこともお知らせください。
ベストアンサー1
あなたはテンプレートコンテキストプロセッサ:
myapp/context_processors.py
:
from django.contrib.auth.models import User
from myapp.models import Project
def users_and_projects(request):
return {'all_users': User.objects.all(),
'all_projects': Project.objects.all()}
そしてこのプロセッサをTEMPLATE_CONTEXT_PROCESSORS
Django バージョン < 1.8 の設定:
TEMPLATE_CONTEXT_PROCESSORS = (
...
'myapp.context_processors.users_and_projects',
)
Django バージョン >= 1.8 の場合は、設定のcontext_processors
リストに追加します。OPTIONS
TEMPLATES
TEMPLATES = [
{
...
'OPTIONS': {
'context_processors': [
...
'myapp.context_processors.users_and_projects',
],
},
},
]
コンテキストプロセッサはすべてのリクエストに対して実行されます。レンダリングを使用するビューに対してのみこれらのクエリを実行したい場合はbase.html
、別の解決策としてカスタム割り当てタグ:
@register.assignment_tag
def get_all_users():
return User.objects.all()
@register.assignment_tag
def get_all_projects():
return Project.objects.all()
テンプレートでは次のようになりますbase.html
:
{% load mytags %}
{% get_all_users as all_users %}
<ul>
{% for u in all_users %}
<li><a href="{{ u.get_absolute_url }}">{{ u }}</a></li>
{% endfor %}
</ul>
{% get_all_projects as all_projects %}
<ul>
{% for p in all_projects %}
<li><a href="{{ p.get_absolute_url }}">{{ p }}</a></li>
{% endfor %}
</ul>