2011-10-17 5 views
8

私はDjangoプロジェクトでカスタムパーミッションアプリケーションを実装していますが、特定のオブジェクトインスタンスに対するログインユーザーの権限をチェックするカスタムテンプレートタグを実装する方法が失われています。チェックの結果に基づいてHTMLを表示します。私が今持っている何if..elseカスタムテンプレートタグ

は(擬似コード)である:

{% check_permission request.user "can_edit" on article %} 
    <form>...</form> 
{% endcheck %} 

( 'check_permissionは' 私のカスタムテンプレートタグです)。

templatetagは、ユーザー、権限、およびオブジェクトインスタンスを取り込み、囲まれたHTML(フォーム)を返します。これは現在正常に動作します。

私は何がやりたい、のようなものです:

{% if check_permission request.user "can_edit" on article %} 
    <form>...</form> 
{% else %} 
    {{ article }} 
{% endif %} 

私はおよそthe assignment tagを読んだが、私の恐怖は、私が以前上書きされる可能性があります意味(これでコンテキスト変数空間を汚染だろうということです許可コンテキスト変数)。言い換えれば、コンテキスト変数が異なるレベル(私の場合はビュー、ミドルウェア、今はこの割り当てテンプレートタグ)で定義されているので、私は保守性について心配しています。

答えて

13

if文の中でテンプレートフィルタを使用できます。だから、フィルタとして、あなたのタグを書き換えることができます:それはフィルターに種類の異なる複数の引数を渡すためにトリッキーだと

{% if request.user|check_can_edit:article %} 

注ので、私が使用した上で、あなたはおそらく、権限ごとに1つのフィルタを使用したいと思いますcheck_can_edit

+0

ありがとうございます、フィルタは確かにオプションになる可能性があります。私は、しかし、(インスタンスの基本的なCRUDだけでなく、いくつかの非常に具体的なもの)異なるアクセス許可を予見します。つまり、同じ量のカスタムテンプレートフィルタを作成する必要があります。おそらく、私は自分のカスタムアクセス許可モデルを考え直すべきでしょう。フィルターに複数の引数を渡すのが難しいと言うなら、それが可能であることを意味しますか?私はそうではないと思っていたので、これをちょっと明確にすることができますか? – LaundroMat

+1

将来の訪問者へのアップデート:私は連鎖したフィルタで解決しようと考えています(例えば '{{request.user | has_permission:" entries.entry.can_edit、 "| has_permission_on:article}}'。)カスタムhas_permissionテンプレートフィルタユーザーと必要な権限を返します。has_permission_onはこれらの値を受け取り、記事変数と照合してTrueまたはFalseを返します。 – LaundroMat

12

テンプレートの可読性を向上させるために、Pythonコードのいくつかの行を書きたい場合は、間違いなくこれを行うことができます。 :)

変数を使用する場合は、タグの内容を自分で解析する必要があります。必要なパラメータも解析して解決する必要があります。

{% load mytag %} 
{% mytag True %}Hi{% else %}Hey{% endmytag %} Bro 

または変数を持つ:

以下の実装タグはこのように使用することができますので、

{% mytag myobject.myflag %}Hi{% else %}Hey{% endmytag %} Bro 

、ここで私はそれをやった方法です:

from django.template import Library, Node, TemplateSyntaxError 

register = Library() 

@register.tag 
def mytag(parser, token): 
    # Separating the tag name from the "test" parameter. 
    try: 
     tag, test = token.contents.split() 
    except (ValueError, TypeError): 
     raise TemplateSyntaxError(
      "'%s' tag takes two parameters" % tag) 

    default_states = ['mytag', 'else'] 
    end_tag = 'endmytag' 

    # Place to store the states and their values 
    states = {} 

    # Let's iterate over our context and find our tokens 
    while token.contents != end_tag: 
     current = token.contents 
     states[current.split()[0]] = parser.parse(default_states + [end_tag]) 
     token = parser.next_token() 

    test_var = parser.compile_filter(test) 
    return MyNode(states, test_var) 


class MyNode(Node): 
    def __init__(self, states, test_var): 
     self.states = states 
     self.test_var = test_var 

    def render(self, context): 
     # Resolving variables passed by the user 
     test_var = self.test_name.resolve(context, True) 

     # Rendering the right state. You can add a function call, use a 
     # library or whatever here to decide if the value is true or false. 
     is_true = bool(test_var) 
     return self.states[is_true and 'myvar' or 'else'].render(context) 

はまた、それでおしまい。 HTH。

+0

ここに本当の答えがあります – snakesNbronies