首页 > 解决方案 > 如何从Django3.0模板内的请求对象中获取用户的组名?

问题描述

我有两组 -admincustomer. 对于导航栏,我想对属于customer组的用户隐藏一些导航链接。为此,我使用以下代码:-

导航栏.html

{% load static %}

<style>
.hello-msg{
  font-size:18px;
  color:#fff;
  margin-right:20px;
}
</style>

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <a class="navbar-brand" href="#">Navbar</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarNav">
    <ul class="navbar-nav">
      {% if request.user.groups.first() == 'admin' %}
      <li class="nav-item active">
        <a class="nav-link" href="{% url 'home' %}">Dashboard</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="{% url 'products' %}">Products</a>
      </li>
      {% endif %}
    </ul>
  </div>

  <span class="hello-msg">Hello, {{request.user}}</span>
  <span><a class="hello-msg" href="{% url 'logout' %}">Logout</a></span>
</nav>

但是,有了这个我得到以下错误: -

Traceback (most recent call last):
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/smartif.py", line 175, in translate_token
    op = OPERATORS[token]
KeyError: 'request.user.groups.first()'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/home/vineet/projects/Multi-tenant/other/accounts/decorators.py", line 39, in wrapper_function
    return view_func(request, *args, **kwargs)
  File "/home/vineet/projects/Multi-tenant/other/accounts/views.py", line 36, in home
    return render(request, 'accounts/dashboard.html', context)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/shortcuts.py", line 19, in render
    content = loader.render_to_string(template_name, context, request, using=using)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/loader.py", line 62, in render_to_string
    return template.render(context, request)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/base.py", line 171, in render
    return self._render(context)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/base.py", line 936, in render
    bit = node.render_annotated(context)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/base.py", line 903, in render_annotated
    return self.render(context)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/base.py", line 936, in render
    bit = node.render_annotated(context)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/base.py", line 903, in render_annotated
    return self.render(context)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/loader_tags.py", line 176, in render
    template = context.template.engine.get_template(template_name)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/engine.py", line 143, in get_template
    template, origin = self.find_template(template_name)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/engine.py", line 125, in find_template
    template = loader.get_template(name, skip=skip)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/loaders/base.py", line 30, in get_template
    contents, origin, origin.template_name, self.engine,
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/base.py", line 156, in __init__
    self.nodelist = self.compile_nodelist()
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/base.py", line 194, in compile_nodelist
    return parser.parse()
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/base.py", line 477, in parse
    raise self.error(token, e)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/base.py", line 475, in parse
    compiled_result = compile_func(self, token)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/defaulttags.py", line 951, in do_if
    condition = TemplateIfParser(parser, bits).parse()
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/defaulttags.py", line 884, in __init__
    super().__init__(*args, **kwargs)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/smartif.py", line 166, in __init__
    mapped_tokens.append(self.translate_token(token))
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/smartif.py", line 177, in translate_token
    return self.create_var(token)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/defaulttags.py", line 887, in create_var
    return TemplateLiteral(self.template_parser.compile_filter(value), value)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/base.py", line 562, in compile_filter
    return FilterExpression(token, self)
  File "/home/vineet/projects/env-cosgrid/lib/python3.6/site-packages/django/template/base.py", line 662, in __init__
    "from '%s'" % (token[upto:], token))
django.template.exceptions.TemplateSyntaxError: Could not parse the remainder: '()' from 'request.user.groups.first()'

我尝试通过这样传递上下文字典:-

视图.py

...
context = { 'group': request.user.groups.first() }

return render(request, 'accounts/dashboard.html', context)
...

导航栏.html

...
 {% if group == 'admin' %}
      <li class="nav-item active">
        <a class="nav-link" href="{% url 'home' %}">Dashboard</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="{% url 'products' %}">Products</a>
      </li>
      {% endif %}
...

但是这样一来,if块中的任何导航链接都不会为任何用户呈现。

我无法修复此错误。任何提示将不胜感激。

标签: djangodjango-templates

解决方案


您不能在模板中调用函数。如果对象是可调用的,Django 会自动调用它,所以你应该指定条件为:

{% if request.user.groups.first.name == 'admin' %}
    …
{% endif %}

这里.name是必要的,否则你会得到一个Group对象,它不等于一个字符串。

话虽如此,我不确定上述是否是一个好主意。想象一下,稍后您引入了额外的组,然后作为组成员的用户有时会看到该项目,有时看不到,因为不同查询之间的顺序可能会有所不同。


推荐阅读