根据用户是否为员工在模板中定义变量

时间:2010-11-09 17:47:38

标签: python django django-templates django-1.2

我正在尝试显示大约20列的html值表,其中说员工用户看到列的一个子集,而非员工用户看到列的另一个子集。我可能想稍后定义更多类型的用户。现在我有三个静态标题行,所以模板看起来像

<table>
<tr>
  <th>Col A</th>
  {% if user.is_staff %}<th>Col B</th>{% endif %}
  ...
  {% if not user.is_staff %}<th>Col K</th>{% endif %}
</tr>
<tr>
  <td>Col A second header</td>
  {% if user.is_staff %}<td>Col B second header</td>{% endif %}
  ...
  {% if not user.is_staff %}<td>Col K second header</td>{% endif %}</tr>
<tr><td>Col A third header</td>  ...  </tr>

{% for obj in object_list %}
<tr>
  <td>{{ obj.col_a }}</td>
  {% if user.is_staff %}<td>{{ obj.col_b }}</td>{% endif %}
  ...
  {% if not user.is_staff %}<td>{{ obj.col_k }}</td>{% endif %}
</tr>
{% endfor %}</table>

但是,我每次都发现非DRY,如果我想要更改用户类型可以看到列,我必须在4个位置更改它。或者如果我想定义多个不同类别的用户,我必须使用复杂的if语句。我更喜欢像

这样的东西
 {% if show_col_a %}<td>{{obj.col_a }}</td>{{% endif %}

我可以在模板顶部(或可能在视图中)定义user.is_staff可以看到show_col_a。这样的事情可能吗?我正在使用通用视图(object_list)。也许修改所有用户以某种方式拥有属性user.show_col_a并执行{%if user.show_col_a%}?我不确定如何向用户添加布尔属性。

编辑:可能希望多个用户使用自定义视图(例如,staff_view; admin_view,unprivileged等),因此如果语句变得难以处理。单元格的内容通常比{{obj.col_b}}更复杂;尝试简化问题以达到目的。 E.g:

<td>{% if obj.custom_address %}
  {{ obj.custom_address.webprint|safe }}
{% else %}
  {{ obj.business.address.webprint|safe }}
{% endif %}</td>

此外,多个模板可以使用简单的开关,例如:     {%if user.is_staff%}        {%include“template_staff.html”%}     {%else%} {%if user.is_admin%}        {%include“template_admin.html”%}     {%else%}        {%include“template_other.html”%}     {% 万一 %}     {%endif%}

我发现它根本不是DRY;例如,必须在三个模板中复制对模板的每个编辑。我想我可以创建一个脚本,读取从django之外的某些super_template生成三个模板,但它变得非常不优雅。

1 个答案:

答案 0 :(得分:2)

这很大程度上取决于您拥有的视图和模板。

方法:

  • 制作一个公共模板和员工模板,并添加一个简单的方法来动态更改视图中的模板。
  • 制作模板标签:

    {%is_staff myvar%}

标记代码:

class IsStaffNode(Node):
    def __init__(self, var):
        self.var = var

    def render(self, context):
        if context['user'].is_staff():
            return var.resolve(context)
        return ""


@register.tag
def is_staff(parser, token):
    var = parser.compile_filter(token.split_contents()[1])
    return IsStaffNode(var)

家庭作业:将其作为一个块标记以包含td,以便显示全部或全部。

{% isstaff myvar %}<td>{{ myvar }}</td>{% endisstaff %}

这种方式比2个不同的模板更耗费人力,但是如果你想尝试,操纵上下文(或仅为块创建单独的上下文)might be useful

  • 制作一个上下文处理器,如果用户是工作人员,则用一些变量填充上下文,如果不是,则创建一个变量。
  • 制作一个包含模板的标签(从IncludeNode继承)并操纵上下文。