定义一个基于用户是工作人员或不

问题描述:

我试图显示值的HTML表,约20列,其中工作人员说用户看到列的一个子集,非工作人员的用户看到的列的另一个子集在模板变量。我可能想在以后定义更多类型的用户。现在,现在我有三个静态标题行,所以模板看起来像定义一个基于用户是工作人员或不

<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> 

不过,我觉得非干成每一次,如果我想改变,如果一个用户类型可以看到一个栏,我不得不改变它在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,非特权等),因此,如果语句会得到笨拙。单元格的内容通常比{{obj.col_b}}更复杂;尝试简化问题以达到目的。例如:

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

而且同时多个模板将与一个简单的开关一样工作: {%如果user.is_staff%} { %包括 “template_staff.html” %} { 其他%%} {%如果user.is_admin%} { %包括 “template_admin.html” %} { 其他%%} { %包括 “template_other.html” %} { ENDIF%%} { ENDIF%%}

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

这取决于什么查看你和模板很多。

方法可以做到:

  • 做出公开模板和工作人员的模板,并添加一个简单的方法来改变在运行的意见的模板。
  • 做出模板标签:

    {%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继承)和操纵上下文的标签。
+0

不希望每个用户类都有模板(可能会延长到稍后有几个用户类;难以维护)。更重要的是拥有与用户或组用户所属的权限相关的字典。我看到我怎么可以修改你的IsStaffNode.render来改变返回“​​”+ var.resolve(context)+“”,但是表格中的一行比我想象的要复杂得多。例如,在单元中具有if语句。 – 2010-11-09 18:36:02