Get user group in a template

26,169

Solution 1

The standard Django way of checking permissions is by the individual permission flags rather than testing for the group name.

If you must check group names, being aware that Users to Groups is a many-to-many relationship, you can get the first group in the list of groups in your template with something like this:

{{ user.groups.all.0 }}

or using it like this in a conditional (untested but should work):

{% ifequal user.groups.all.0 'Sales' %}
   ...
{% endif %}

If you go with the preferred permission model you would do something like the following.

...

  {% if perms.vehicle.can_add_vehicle %}
    <li><a href="/add_vehicle">Add a New Record </a></li>
  {% endif %}
  {% if perms.vehicle.can_change_vehicle %}
    <li><a href="/edit_vehicle">Edit Existing Record </a></li>
  {% endif %}

...

These are the permissions automatically created for you by syncdb assuming your app is called vehicle and the model is called Vehicle.

If the user is a superuser they automatically have all permissions.

If the user is in a Sales group they won't have those vehicle permissions (unless you've added those to the group of course).

If the user is in a Management group they can have those permissions, but you need to add them to the group in the Django admin site.

For your other question, redirect on login based on user group: Users to Groups is a many-to-many relationship so it's not really a good idea to use it like a one-to-many.

Solution 2

user.groups.all.0.name == "groupname"

Solution 3

Create a user_tags.py in your app/templatetags follow above:

# -*- coding:utf-8 -*-
from __future__ import unicode_literals

# Stdlib imports

# Core Django imports
from django import template

# Third-party app imports

# Realative imports of the 'app-name' package


register = template.Library()


@register.filter('has_group')
def has_group(user, group_name):
    """
    Verifica se este usuário pertence a um grupo
    """
    groups = user.groups.all().values_list('name', flat=True)
    return True if group_name in groups else False

And finally in template use it:

{% if request.user|has_group:"Administradores"%}
      <div> Admins can see everything </div>
{% endif %}

Solution 4

If you are working with Custom User Model (best practice with Django), you can create a method:

CustomUser(AbstractUser):
    # Your user stuff

    def is_manager(self):
        return self.groups.filter(name='Management').exists()

Then inside your template you just call it this way:

{% if user.is_manager %}
    {# Do your thing #}
{% endif %}

That method will be also useful validating permission in other parts of your code (views, etc.)

Share:
26,169
Mirko Brombin
Author by

Mirko Brombin

Open Source &amp; Linux supporter.

Updated on June 16, 2021

Comments

  • Mirko Brombin
    Mirko Brombin about 3 years

    I want to display a menu that changes according to the user group of the currently logged in user, with this logic being inside of my view, and then set a variable to check in the template to determine which menu items to show....I'd asked this question before, but my logic was being done in the template. So now I want it in my view...The menu looks as below

       <ul class="sidemenu">
        <li><a href="/">General List </a></li>
        <li><a href="/sales_list">Sales List </a></li>
        <li><a href="/add_vehicle">Add a New Record </a></li>
        <li><a href="/edit_vehicle">Edit Existing Record </a></li>
        <li><a href="/filter">Filter Records </a></li>
        <li><a href="/logout">Logout </a></li>
      </ul>
    

    Suppossing the user is management, they'll see everything...But assuming the user is in the group sales, they'll only see the first two and the last two items...and so on. I also want a dynamic redirect after login based on the user's group. Any ideas?

  • zeridon
    zeridon about 8 years
    Just don't forget to {% load user_tags %} in the template.
  • AlexW
    AlexW about 8 years
    how can i use this code to check if in groupA or groupB for example?
  • rammanoj
    rammanoj over 5 years
    I am not sure why but this is not working for me {% ifequal user.groups.all.0 'Sales' %} ... {% endif %}
  • rammanoj
    rammanoj over 5 years
    however this worked user.groups.all.0.name == "groupname" I guess in the first case a queryset and string being compared so it doesnt work ??
  • Anthony Roberts
    Anthony Roberts over 5 years
    user.groups.all.0.name == "groupname" is the correct usage here. @rammanoj deserves some props for this tidbit. I also noticed that the closing tag needs to be endifequal, not endif.
  • Aaron Scheib
    Aaron Scheib about 5 years
    definitely my preferred answer as you don't have to create a custom template tag.
  • Shoo Limberger
    Shoo Limberger almost 4 years
    @AlexW {% if request.user|has_group:"groupA" or request.user|has_group:"groupB" %} <div> Admins can see everything </div> {% endif %}