Vineet
Vineet

Reputation: 783

How to get group name of a user from request object inside template in Django3.0?

I have two groups - admin and customer. For navbar, I want to hide some navigation links from users belonging to customer group. For this, I am using following code:-

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

However, with this I am getting following error:-

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()'

I tried by passing context dictionary like this:-

views.py

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

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

Navbar.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 %}
...

But with this, none of nav links in the if block are rendered for any user.

I am unable to fix this error. Any hint would be appreciated.

Upvotes: 1

Views: 75

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477160

You can not call functions in a template. If the object is callable, Django will automatically call it, so you should specify the condition as:

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

The .name is necessary here, since otherwise you get a Group object, and that is not equal to a string.

That being said, I am not sure that the above is a good idea. Imagine that later you introduce extra groups, then users that are members of a group will sometimes see the item, and sometimes not, because the order can vary between different queries.

Upvotes: 1

Related Questions