この質問が数週間前に行われたことは承知していますが、あなたのコメントの 1 つでhttp://code.google.com/p/greatlemers-django-tools/について言及されていたので、私が意見を述べたいと思いました。
プロジェクトはまだアクティブですが (現時点では少し後回しになっていますが)、あなたが求めているほど DRY かどうかはわかりません。メニュー項目のモデル オブジェクトで 1 回、ビューで 1 回、2 回アクセス許可を指定する必要があります。これは必ずしも悪いことではありませんが、メニュー項目で定義するパーミッションはビューのものとは少し異なる場合があります。
すべてを 1 か所で行いたい場合は、urls.py で使用するユーティリティ関数を組み合わせてビューに制限を追加し、その制限を特別なテンプレート タグで使用するためにどこかに保存することをお勧めします。私はそれがこのように見えるかもしれないと想像します。
# Stored in a file named access_check_utils.py say.
from django.conf.urls.defaults import url
from django.core.urlresolvers import get_callable
from django.contrib.auth.decorators import permission_required
access_checked_urls = {}
def access_checked_url(regex, view, kwargs=None, name=None, prefix='', perms=None, login_url=None):
if perms is None:
perms = []
callback = None
if callable(view):
callback = view
elif isinstance(view, basestring):
if prefix:
view_path = "%s.%s" % (prefix, view)
else:
view_path = view
try:
callback = get_callable(view_path)
except:
callback = None
if callback is not None:
# Add all the permissions
for perm in perms:
callback = permission_required(perm, login_url=login_url)(callback)
if name is not None:
access_checked_urls[name] = perms
else:
callback = view
return url(regex, callback, kwargs=kwargs, name=name, prefix=prefix)
これは、通常の url と同じ方法で呼び出される urls.py で必要なピットに対して機能するはずですが、perms と login_url パラメーターが追加されています (perms は関連するすべてのパラメーターのリストである必要があります)。
# In a templatetag folder somewhere
from django import template
from django.core.urlresolvers import
# This needs to point to the right place.
from access_check_utils import access_checked_urls
register = template.Library()
@register.inclusion_tag("access_checked_link.html", takes_context=True)
def access_checked_link(context, title, url, *args, **kwargs):
perms = access_checked_urls.get(url, [])
if not perms:
allowed = True
else:
allowed = context.request.user.has_perms(perms)
return { 'allowed': allowed,
'url': reverse(url, *args, **kwargs),
'title': title }
これには、次のような関連付けられたテンプレート ファイルがあります。
{% if allowed %}<a href="{{ url }}">{{ title }}</a>{% endif %}
私はこれを完全にはテストしていませんが、動作するはずです (または、動作するはずの何かの良い基礎になるはずです)。おそらく、このようなものを gdt_nav に追加して、これらの基本アクセス許可が存在するかどうかを確認し、追加された追加のアクセス許可を確認することも検討します。
これが役立つことを願っています。
--
G