2012-06-10 8 views
7

私のDjangoアプリケーションは現在、permission_required()関数によって保護されているURLを持っています。Django URLを呼び出さずに必要な権限を探しますか?

この関数は3つの異なる方法で呼び出されます。

  1. ハードコードされたパラメータを持つviews.pyのデコレータです。
  2. 自動生成されたパラメータを持つプレーン関数として、カスタムクラスベースの汎用ビューで使用します。
  3. ハードコードされたパラメータでurls.pyのビューを呼び出す関数として。

私は現在、メニューシステムをアプリケーションに追加しています。ユーザーが各メニューエントリのURLを要求する権限を持っているかどうかをメニューエントリに反映させる必要があります。 (そのエントリをグレイアウトするか隠すかによって)

のURLに要求されているアクセス許可があるかどうかの問い合わせ方法はありますか?はURLを要求していますか?

私が考えた唯一の解決策は、デコレータをパラメータのない 'menu_permssion_required()'デコレータで置き換え、すべての権限をPython構造体にハードコードすることです。私のカスタムクラスベースのGeneric Viewsは既に必要な権限を自動生成しているので、これは一歩後退しているようです。

現在のユーザーのURLアクセス許可を反映するメニューシステムを作成する方法に関する提案はありますか?

+0

私はいつもテンプレートのメニューをハードコードしていますが、それは簡単で、{%extend%}のコンテキストメニューが可能です。 – jpic

+0

@jplc謝罪、私はあなたのコメントが質問にどのように関係しているか理解できません。これは特にアクセス許可についてです。許可はクロスカッティングであり、URL接頭辞またはそれに類するものにリンクされていません。 – fadedbee

+0

テンプレートのパーミッションをチェックすることができます:https://gist.github.com/25c03f286337c66cc860これはdjangoプロジェクトのかなり標準的なものです。これは私が見たことからdjango permsモジュールのドキュメントです:https:// docs.djangoproject.com/en/1.0/topics/auth/#id6でも、私の主張は、HTMLメニューの「システム」を作るのに費やされた時間が、他のものに費やされる可能性が高いことです。 – jpic

答えて

2

はあなたの問題を解決する方法の例です:

まず、代わりにpermission_requiredの使用にデコレータラッパーを作成します。

from django.contrib.auth.decorators import login_required, permission_required, user_passes_test 
from django.core.exceptions import PermissionDenied 
from functools import wraps 
from django.utils.decorators import available_attrs 

def require_perms(*perms): 
    def decorator(view_func): 
     view_func.permissions = perms 
     @wraps(view_func, assigned=available_attrs(view_func)) 
     def _wrapped_view(request, *args, **kwargs): 
      for perm in perms: 
       return view_func(request, *args, **kwargs) 
      raise PermissionDenied() 
     return _wrapped_view 
    return decorator 

その後、あなたの意見を飾るためにそれを使用する:

@require_perms('my_perm',) 
def home(request): 
..... 

次に、メニュー項目に使用するタグを追加します。

そして最後に、あなたのテンプレートでは、メニューツリーを構築する:

<button href="{{ some_path }} {% if not check_menu_permissions some_path request.user %}disabled="disabled"{% endif %} /> 

N.B.私は最後の部分をタグでテストしていませんが、アイデアがあることを願っています。ここでの魔法は、デコレータのview_funcにパーミッションを追加することです。それから、resolve(path)を使ってアクセスできます。私はこれがパフォーマンスの面でどのように振る舞うかはわかりませんが、結局のところ単なるアイデアです。

EDIT:ちょうど私が同様の問題があったが、それは少し深く行ってきました。..例で

+0

ありがとう、私は一般的な考えが大好きです。私は月末までに実際にどのように動作するかをお知らせします(プロジェクトの期限)。 – fadedbee

2

URLを要求せずにURLに必要なアクセス許可はありますか?

User.has_perm()User.has_module_perms()

現在のユーザーのためのURLの権限を反映したメニューシステムを作成する方法上の任意の提案?

私は本当にこのトピックが好きです。なぜなら、これはジャンゴと一緒にウェブサイトを作ってくれる人に関係しているからです。私は自分自身を介して行ってきたし、coded a menu "system" 2008年に私の最初のジャンゴプロジェクトに戻った。しかし、その後、私はピナックスを試してみた。私は彼らのサンプルプロジェクトから学んだ(非常に多くの)事の一つは、

私は、要求のユーザ権限を尊重したメニュー "システム"を作成する方法をサポートする提案はありません。

私はリクエストのユーザ権限を尊重する簡単なメニューを作成する方法について提案しているので、完全に無関係ではないかもしれません。

  1. 単なるHTMLであなたのメニューを作る、そう頻繁にそれが生成されなければならないことを変えるために起こっているようではないです。これにより、Pythonコードがよりシンプルに保たれます。

  2. settings.TEMPLATE_CONTEXT_PROCESSORSに入れる:'django.core.context_processors.PermWrapper'

  3. をUser.has_permsに{{ perms }} proxyを使用してください。

例:

私は、ナビゲーションを保つ方法です
{% if perms.auth %} 
    <li class="divider"></li> 

    {% if perms.auth.change_user %} 
    <li> 
     <a href="{% url admin:auth_user_changelist %}">{% trans 'Users' %}</a> 
    </li> 
    {% endif %} 

    {% if perms.auth.change_group %} 
    <li> 
     <a href="{% url admin:auth_group_changelist %}">{% trans 'User groups' %}</a> 
    </li> 
    {% endif %} 

{% endif %} 
{# etc, etC#} 

シンプル愚か、および方法のうち。しかし、私はいつもメニューから離れていないan autocompleteも含めて、ユーザーが任意の詳細ページに簡単にナビゲートできるようにしています。だから、これは私がdjangoプロジェクトのナビゲーションについて知っていることです。私は他の答えを読むことを熱望しています!ここで

1

をバグを修正。ただの許可の代わりに、私はふたをしたユーザー(すなわち、is_staff、またはuser.units.count() > 1)に基づいた他のテストも望んでいました。ビューとテンプレートにこれらを複製すると、エラーが発生しやすくなります。

ビューオブジェクトをイントロスペクトして、それをラッピングしているすべてのデコレータを見ることができます(私の場合、最初の引数はuまたはuserです)。それらがすべて合格したら、リンクのレンダリングを許可します。

Get all decorators wrapping a functionは、もう少し詳しく説明します。 {% url %}Django-menus)の便利な代替品にこれをラップするアプリがあります。

+0

ありがとう、私はDjangoメニューを見て、私が必要とするものがあるかどうかを見ます。もし私が自分でこれをコード化しなければならないなら(私は自分のカスタムパースメントデコレータを使うので)、私はTishoの答えと一緒に行くでしょう。 – fadedbee

関連する問題