【问题标题】:Using django permissions in template tags在模板标签中使用 django 权限
【发布时间】:2017-09-10 02:37:38
【问题描述】:

我目前正在检查模板中的权限,以决定是否要显示特定链接。

这对于在我的普通模板中扩展的 base.html 非常有效:

base.html

{% if perms.myapp.can_add %}
    #display link
{% endif %}

我的模板

{% extends "riskass/base.html" %}
{% block content %}
    # do stuff #
{% endblock %}

但我也对模板中的重复项目使用模板标签,并且相同的权限检查似乎在它们中不起作用。

有人知道我可能做错了什么吗?谢谢!

我的模板

{% extends "riskass/base.html" %}

{% load show_items %}

{% block content %}
    # do stuff #
    {% show_items items_list%}
{% endblock %}

templatetags/show_items.py

from django import template

register = template.Library()

@register.inclusion_tag('myapp/show_items.html')
def show_items(items):
    return {'items': items}

myapp/show_items.html

{% for item in items%}

    # display stuff: this works
    ...

    # check permissions: 
     {% if perms.myapp.can_add %}
        #display other link: doesn't do anything
     {% endif %}

【问题讨论】:

  • 作为建议:使用{% load show_item%}是不够的,还需要使用{% show_item AnObject %}
  • 是的,是的,在示例中忘记了它,但我正确地使用了它;模板标签按预期工作,而不是其中的 Auth 部分

标签: python django oauth


【解决方案1】:

perms 是您的模板“我的模板”在其中呈现的模板上下文的一部分。但是您的包含标签模板 myapp/show_item.html 默认情况下具有自己的上下文,并且不会继承 perms 或任何其他模板变量,除非您通过在标签注册中传递 takes_context=True 来安排它,并且只做一点将部分或全部上下文传递到标签模板上下文的代码。

在 Django 文档中有一个例子:

https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/#inclusion-tags

这有点令人困惑,因为文档似乎暗示您可以或者将自己的参数传递给标记方法传递上下文,但不能同时传递。然而事实并非如此。当takes_context=True 传递给@register.inclusion_tag() 时,效果将是django 将context 作为第一个参数传递给您的标签函数,然后是您希望传递给您的标签的任何参数。传递的上下文是您的标签所在模板的上下文。因此您可以从那里获取您需要的内容并将其传递给包含的模板,例如:

@register.inclusion_tag('riskass/show_ratings.html', takes_context=True)
def show_ratings(context, ratings):
    return {
        'ratings': ratings,
        'perms': context.get('perms', None)
    }

标签用法如下所示:

{% show_ratings ratings_list %}

在另一个 Stack Overflow 问题和答案中有一些有用的信息,尽管它与您可能想要查看的问题并不完全相同:

Pass a context variable through an inclusion tag

【讨论】:

  • 感谢您的解释;基本上我必须找到一种方法将 perms 上下文变量传递给包含标签。这个技巧有效,但并不理想……:def show_ratings(items, perms=[]): return { 'items': items, 'perms': perms }。然后你调用包含标签: {% show_items items_list perms %}
  • 我不得不使用它,因为我的 items_list 在我的应用程序中并不总是以相同的方式调用。你怎么看?
  • 好的.. Django 文档暗示您可以传递上下文或传递您自己的参数,而不是两者。但我查看了 Django 源代码:django/template/library.py TagHelperNode.get_resolved_arguments() 似乎先传递上下文,然后再传递您自己的参数。因此,您可以在包含标签功能中访问两者。但是如果事实证明你只能拥有一个或另一个,你可以像你一样传递 perms,或者你可以使用上下文并将你的标签包装在一个 {% with %} 标签中来设置你需要的变量在上下文中改变。
  • 但我在阅读文档时的印象是,上下文变量是在你有takes_context = true的地方隐式传递的;那么你怎么能同时传递上下文和列表呢?
  • 不,在你的标签声明中使用takes_context=True
猜你喜欢
  • 2014-03-20
  • 2015-02-27
  • 1970-01-01
  • 2022-11-25
  • 1970-01-01
  • 2015-04-13
  • 2022-10-16
  • 2011-06-15
  • 2018-11-19
相关资源
最近更新 更多