Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I change a Django Template based on the User's Group?

Right now I have two different groups of users on my site: customers and businesses.

Right now I am only using one login that allows both user groups to see their profile page.

However, there are portions of the profile page I only want the Customer to see and portions I only want the business to see. How can I go about limiting what each group sees on this page?

Should I do it in the template with some sort of if statement? or is there some other solution anyone can let me know about?

like image 599
chris Avatar asked Jan 02 '11 07:01

chris


People also ask

How do I inherit a template in Django?

extends tag is used for inheritance of templates in django. One needs to repeat the same code again and again. Using extends we can inherit templates as well as variables.

What does {{ NAME }} this mean in Django templates?

What does {{ name }} this mean in Django Templates? {{ name }} will be the output. It will be displayed as name in HTML. The name will be replaced with values of Python variable.

How do I perform query filtering in Django templates?

The easiest is to do the filtering, then pass the result to render_to_response . Or you could write a method in your model so that you can say {% for object in data. filtered_set %} . Finally, you could write your own template tag, although in this specific case I would advise against that.

Which option does Django templates accept?

DjangoTemplates engines accept the following OPTIONS : 'autoescape' : a boolean that controls whether HTML autoescaping is enabled. It defaults to True . Only set it to False if you're rendering non-HTML templates!


4 Answers

This is probably too old for you to care any more, but I stumbled here myself before figuring it out on my own. For posterity, I found the following solution:

In your view, add something like this:

is_customer = request.user.groups.filter(name='Customers').exists()

In your template:
{% if is_customer %} customer stuff here {% endif %}

It relies on the fact that an if clause in a template will be evaluate to false for an empty list.

like image 112
jorelli Avatar answered Sep 20 '22 05:09

jorelli


If you want to avoid adding anything to your view functions, and you’re using the auth context processor (django.contrib.auth.context_processors.auth) and RequestContext as per @thyagx’s answer, then you could use a template snippet like that suggested in this Google Groups post:

{% for group in user.groups.all %}
    {% if group.name == 'customers' %}
        {% comment %}Customer-specific code goes here{% endcomment %}
    {% endif %}
{% endfor %}

It’s a bit verbose, but it does mean you don’t have to do anything in your view (aside from using RequestContext), or write a custom context processor.

like image 43
Paul D. Waite Avatar answered Sep 20 '22 05:09

Paul D. Waite


I implemented this through a template tag, based on what I found here. Perhaps it can be useful to someone.

In utils/utils_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):
    try:
        group = Group.objects.get(name=group_name)
    except:
        return False  # group doesn't exist, so for sure the user isn't part of the group

    # for superuser or staff, always return True
    if user.is_superuser or user.is_staff:
        return True

    return user.groups.filter(name=group_name).exists()

Then in the template itself:

{% load utils_extras %}
{% if user|has_group:"mygroup" %}
like image 22
SaeX Avatar answered Sep 20 '22 05:09

SaeX


What I did to solve this is:

  1. I created a custom context processor which basically inserts new variables for you to use in your templates and added it to my settings. See more @ https://docs.djangoproject.com/en/1.3/ref/templates/api/#django.template.RequestContext:

    TEMPLATE_CONTEXT_PROCESSORS = (
        'django.core.context_processors.debug',
        'django.core.context_processors.i18n',
        'django.core.context_processors.media',
        'django.core.context_processors.static',
        'django.contrib.auth.context_processors.auth',
        'django.contrib.messages.context_processors.messages',
        'common.user_context.user_context'
    )
    
  2. I went on to write the function user_context inside the file user_context, mine is like so:

    def user_context(request):
        if request.user.is_authenticated():
            is_admin = is_local_admin(request.user)
        else:
            is_admin = False
    
        return {
            'is_local_admin': is_admin
        }
    

    is_local_admin is just a function that checks if the user belongs to the Admins group or not.

  3. Whenever I need this is_local_admin information in my template I use this to render it in my view, for example:

    return render_to_response('create_user.html', {
        'form': form
    }, context_instance=RequestContext(request))
    

The important part is the RequestContext, which loads the custom context processor we build in step 1.

Now in your template you can just use:

{% if is_local_admin %}
    <h1>You can see this</h1>
{% else %}
    <h1>Nothing here</h1>
{% endif %}

Hope this helps someone. In summary: take a look at custom context processors, they are worth the read.

like image 35
avlnx Avatar answered Sep 20 '22 05:09

avlnx