Reputation: 18745
How to check in template whether user belongs to some group?
It is possible in a view
which is generating the template
but what if I want to check this in base.html
which is an extending template (it does not have it's own view function)?
All of my templates extends base.html
so it is not good to check it in each view
.
The base.html
contains upper bar, which should contain buttons depending on in which group
logged user is (Customers, Sellers).
In my base.html
is:
{% if user.is_authenticated %}
which is not enough because I have to act differently to users from Customers
and users from Sellers
.
So the thing I want is:
{% if user.in_group('Customers') %}
<p>Customer</p>
{% endif %}
{% if user.in_group('Sellers') %}
<p>Seller</p>
{% endif %}
Upvotes: 71
Views: 52967
Reputation: 113
In my case the problem was, I was using {% load filter_method_name %}
I had to change to {% load filename %}
For example,
app/
__init__.py
models.py
templatetags/
__init__.py
auth_extras.py
views.py
Here, template taq will be {% load auth_extras %}
I then had to restart the server.
Upvotes: 1
Reputation: 77
First You need to define a custom filter function inside has_group.py
from django import template
from xx.models import Xuser
register = template.Library()
@register.filter(name='has_group')
def has_group(user, group_name):
try:
group = Xuser.objects.get(email=user.email)
if group.role == group_name:
return True
else:
return False
except Xuser.DoesNotExist:
return False
return group
in django settings.py
file you need to add
'libraries': {
'my_templatetag': 'xx.templates.has_group',
},
inside TEMPLATES = []
and then add
{% load my_templatetag %}
in your example.html
in last
{% if user|has_group:"admin" %}
{% endif %}
Upvotes: 0
Reputation: 481
You can use this:
{% for group_for in request.user.groups.all %}
{% if group_for.name == 'Customers' %}
Text showed to users in group 'Customers'
{% elif group_for.name == 'Sellers' %}
Text showed to users in group 'Sellers'
{% endif %}
{% endfor %}
This is iterating through groups related to the user who makes the request and printing the text if the name of the iterated group equals 'Customers', 'Sellers', etc
Upvotes: 8
Reputation: 5607
You need custom template tag:
from django import template
register = template.Library()
@register.filter(name='has_group')
def has_group(user, group_name):
return user.groups.filter(name=group_name).exists()
In your template:
{% if request.user|has_group:"mygroup" %}
<p>User belongs to my group
{% else %}
<p>User doesn't belong to mygroup</p>
{% endif %}
Source: http://www.abidibo.net/blog/2014/05/22/check-if-user-belongs-group-django-templates/
Docs: https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
Upvotes: 116
Reputation: 2346
The easiest way that I found is by adding all groups name to the context by using a context_preprocessor
In your app create a file context_processors.py
and add the following content:
def user_groups_processor(request):
groups = []
user = request.user
if user.is_authenticated:
groups = list(user.groups.values_list('name',flat = True))
return {'groups': groups}
in your settings, add the new context processor
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
# ... some options here ...
"context_processors": [
"my_app.context_processors.user_groups_processor"
],
},
},
]
Or if you prefer in settings.py
TEMPLATES[0]['OPTIONS']['context_processors'].append("my_app.context_processors.user_groups_processor")
After that in your templates you can use:
{% if 'vip' in groups %}
<p>Paragraph only visible to VIPs</p>
{% endif %}
Upvotes: 5
Reputation: 855
I'd say that the best way is:
yourapp/templatetags/templatetagname.py
from django import template
register = template.Library()
@register.filter(name='has_group')
def has_group(user, group_name):
return user.groups.filter(name=group_name).exists()
yourapp/templates/yourapp/yourtemplate.html:
{% load has_group %}
{% if request.user|has_group:"mygroup" %}
<p>User belongs to my group</p>
{% else %}
<p>User does not belong to my group</p>
{% endif %}
EDIT: added line with template tag loading as was advised in comments.
EDIT2: fixed minor typo.
Upvotes: 18
Reputation: 29
Although the answer given by mishbah is right but it didn't work for me.
I am using Django 2.2.7 and i figured out that register = template.Library()
should be replaced with from django.template.defaultfilters import register
.
i hope someone will find it useful.
Upvotes: 1
Reputation: 105
{% if target_group in user.groups.all.0.name %}
# do your stuff
{% endif %}
Upvotes: 2
Reputation: 1097
In your app create a folder 'templatetags'. In this folder create two files:
__init__.py
auth_extras.py
from django import template
from django.contrib.auth.models import Group
register = template.Library()
@register.filter(name='has_group')
def has_group(user, group_name):
group = Group.objects.get(name=group_name)
return True if group in user.groups.all() else False
It should look like this now:
app/
__init__.py
models.py
templatetags/
__init__.py
auth_extras.py
views.py
After adding the templatetags module, you will need to restart your server before you can use the tags or filters in templates.
In your base.html (template) use the following:
{% load auth_extras %}
and to check if the user is in group "moderator":
{% if request.user|has_group:"moderator" %}
<p>moderator</p>
{% endif %}
Documentation: https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/
Upvotes: 36
Reputation: 321
Watch out that you'll get an exception if the group does not exist in the DB.
The custom template tag should be:
from django import template
from django.contrib.auth.models import Group
register = template.Library()
@register.filter(name='has_group')
def has_group(user, group_name):
try:
group = Group.objects.get(name=group_name)
except Group.DoesNotExist:
return False
return group in user.groups.all()
Your template:
{% if request.user|has_group:"mygroup" %}
<p>User belongs to my group
{% else %}
<p>User doesn't belong to mygroup</p>
{% endif %}
Upvotes: 13
Reputation: 119
In your template
{% ifequal user.groups.all.0.name "user" %}
This is User
{% endifequal %}
Upvotes: 11