1

ユーザーの権限に応じて動的なメニューを作成したい。ここドキュメント自体で既に説明したように、次のスニペットを使用してテンプレートでこれを実現できることを知っています。

{% if perms.polls.can_vote %}
    <li>
        <a href="/polls/vote">Vote</a>
    </li>
{% endif %}

しかし問題は、セキュリティ上の理由から、ビューへのアクセスも制限したいということです。ドキュメントで見つけたスニペットは次のとおりです。

from django.contrib.auth.decorators import permission_required

def my_view(request):
    # ...
my_view = permission_required('polls.can_vote', login_url='/loginpage/')(my_view)

これはDRYの原則に反していませんか?各 URL に必要なアクセス許可を 1 か所だけ定義する方法はありませんか? おそらくurls.pyで?

4

2 に答える 2

1

この質問が数週間前に行われたことは承知していますが、あなたのコメントの 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

于 2010-01-02T16:08:24.317 に答える