In every page (base.html
), I want to check whether request.user
has an administrator role from my class UserTypes
and show the admin link. Currently I do something like this:
{% if user.profile.user_types.all %}
{% for user_type in user.profile.user_types.all %}
{% if user_type.name == "ad" %}
<li>
<a href="{% url admin:index %}" class="round button dark ic-settings image-left">Admin</a>
</li>
{% endif %}
{% endfor %}
{% endif %}
user.profile
is simply going from Django's User
to my UserProfile
.
But this seems a little verbose and clunky. Is there a simpler way? Maybe I should be writing my own custom context processor and pass a variable like is_admin
or something, but I never wrote a custom context processor before...
You can add method is_admin
to your UserProfile
model moving business logic to models.
Note that construction like
{% if user.profile.user_types.all %}
{% for user_type in user.profile.user_types.all %}
...
{% endfor %}
{% endif %}
hits 2 sql query to your db. But with
template tag reduces them to 1 hit.
{% with types=user.profile.user_types.all %}
{% if types %}
{% for user_type in types %}
...
{% endfor %}
{% endif %}
{% endwith %}
Actually the best place for this is in models. But you should learn what django offers for your purpose (contrib.auth, permissions, user groups). Probably you reinvent the wheel.
Then condition {% if user_type.name == "ad" %}
shouldn't be hard coded in your python code (especially in templates).