Authorization
Setting up authorization for the sidebar menu and its associated links requires choosing a Policy and then properly using some Decorators or Mixins provided by this package to set permissions on various views. Setting the permissions on the view has the added benefit of not only preventing users from accessing a view, but also automatically hiding links on the sidebar menu from the users that do not have access.
Policy
The first step in using and configuring authorization for views and sidebar menu links is to determine what general policy you want to adhere to. Your choices are:
Loose Policy - By default all sidebar links are visible and accessible to the user.
Majority of sidebar links are visible to all users.
Link will still be visible if you set a permission on that route’s view and that user has the correct permission.
Link will be hidden if you set a permission on that route’s view and the user does not have the correct permission.
Strict Policy - By default all sidebar links are hidden from the user.
Majority of sidebar links are hidden to all users.
Link will become visible if you set a permission on that route’s view and that user has the correct permission.
Link will become visible if you put the route in an explicit whitelist defined in the settings.
Important
The strictness in this policy is related to the visibility of sidebar menu links only. If no permissions are set on a corresponding view, the sidebar menu link is not visible, but the user can still technically gain access to the page assuming that they know the url and directly go to it. To completely block users from a route, you Must define a permission on the view or handle it with some other form of permission checking provided by Django.
Once you have determined what general policy you want to follow, use the corresponding section to properly set up and configure authorization.
Loose Policy
Use the following steps to finish out your policy. Refer to the Configuration section for information about the specific settings in settings.py mentioned below.
Ensure that the
ADMINLTE2_USE_STRICT_POLICY
is either not defined insettings.py
, or is set toFalse
if it is defined.If you are using function based views, read the Function Based Views section and follow the steps in the Loose Decorator Example section to add permissions to views that require permission to access.
If you are using class based views, read the Class Based Views section and follow the steps in the Loose Mixin Example section to add permissions to views that require permission to access.
Strict Policy
Use the following steps to finish out your policy. Refer to the Configuration section for information about the specific settings in settings.py mentioned below.
Ensure that the
ADMINLTE2_USE_STRICT_POLICY
is defined insettings.py
and is set toTrue
.If you are using function based views, read the Function Based Views section and follow the steps in the Strict Decorator Example section to add permissions to views that require permission to access.
If you are using class based views, read the Class Based Views section and follow the steps in the Strict Mixin Example section to add permissions to views that require permission to access.
Add any routes that do not require a specific permission and should be available to everyone to the
ADMINLTE2_STRICT_POLICY_WHITELIST
insettings.py
Function Based Views
Decorators
There are three decorators provided by Django-AdminLTE-2 that can be used on a view to control whether a user has access to both the view, and the visibility of any links in the sidebar that link to that view. Those decorators are:
Login Required Decorator imported with
from django_adminlte_2.decorators import login_required
Permission Required Decorator imported with
from django_adminlte_2.decorators import permission_required
Permission Required One Decorator imported with
from django_adminlte_2.decorators import permission_required_one
Login Required Decorator
@login_required
This decorator will enforce that a user is logged into the system before they can access the view. Django’s default login_required decorator is used behind the scenes and is only recreated in this package in order to add the magic of automatic sidebar link rendering.
When using this decorator on a function view, if the user is not logged in, the user will not be able to access this view nor will they see a sidebar menu entry that maps to this view. However, if the user is logged in, they will see the sidebar link and have access.
from django_adminlte_2.decorators import login_required
@login_required
def demo_css(request):
"""Show examples of extra-features.css"""
return render(request, 'adminlte2/demo_css.html', {
'bootstrap_types': ['primary'],
})
Permission Required Decorator
@permission_required
This decorator will list all required permissions for the view. Django’s default permission_required decorator is used behind the scenes and is only recreated in this package in order to add the magic of automatic sidebar link rendering.
When using this decorator on a function view, if the user does not have all of the permissions that we define in this decorator, the user will not be able to access this view nor will they see a sidebar menu entry that maps to this view. However, if the user does have all of these permissions, they will see the sidebar link and have access.
from django_adminlte_2.decorators import permission_required
@permission_required([
'auth.add_group',
'auth.change_group',
'auth.delete_group'
])
def sample1(request):
"""Show default sample1 page"""
return render(request, 'adminlte2/sample1.html', {})
Permission Required One Decorator
@permission_required_one
This decorator will list the permissions that a user must have at least one of in order to access the view and see the associated sidebar Link.
Note
Django does not provide a similar decorator by default. This decorator is exclusive to this package.
When using this decorator on a function view, if the user does not have at least one of the permissions that we define on this decorator, the user will not be able to access this view nor will they see a sidebar menu entry that maps to this view. However, if the user has at least one of any of these permissions, they will see the sidebar link and have access.
Tip
This decorator is good when you have a landing page for a section of your site and don’t care whether the user can only read or has full edit permissions. Either one should allow the user to see the sidebar link and gain access to the landing page where further restrictions can be used as needed.
from django_adminlte_2.decorators import permission_required_one
@permission_required_one([
'auth.add_permission',
'auth.change_permission',
'auth.delete_permission'
])
def sample2(request):
"""Show default sample2 page"""
return render(request, 'adminlte2/sample2.html', {})
Decorator Examples
Loose Decorator Example
In this example there are four routes, views, and sidebar entries.
Home - should be shown to all users regardless of being logged in or having permission.
Sample 1 - requires two permissions (and thus being logged in) to see and access.
Sample 2 - should require at least one of the listed permissions (and being logged in) to see and access. But, we intentionally forgot to add that permission to demonstrate what will happen.
Demo CSS - requires simply being logged in to see and access.
Note
In the below files, we have purposely made a mistake in regards to the Sample2 view in order to no only demonstrate how the various files and contents work, but also to show what sort of side effects to expect when using the Loose Policy. Below this initial attempt we correct our initial mistake and show the proper configuration as well as what users will see.
settings.py
# Sidebar menu definition.
ADMINLTE2_MENU = [
{
'text': 'Home',
'links': [
{
'route': 'home',
'text': 'Home',
'icon': 'fa fa-dashboard',
},
{
'route': 'sample1',
'text': 'Sample1',
'icon': 'fa fa-bank'
},
{
'route': 'sample2',
'text': 'Sample2',
'icon': 'fa fa-building'
},
{
'route': 'demo-css',
'text': 'Demo CSS',
'icon': 'fa fa-file'
},
]
},
]
# Ensures that we are using the Loose Policy.
ADMINLTE2_USE_STRICT_POLICY = False
urls.py
urlpatterns = [
path('home/', views.home, name="home"),
path('sample1/', views.sample1, name="sample1"),
path('sample2/', views.sample2, name="sample2"),
path('demo-css/', views.demo_css, name="demo-css"),
]
views.py
from django.shortcuts import render
from django_adminlte_2.decorators import (
login_required,
permission_required,
permission_required_one,
)
def home(request):
"""Show home page"""
return render(request, 'adminlte2/home.html', {})
@permission_required(['auth.add_permission', 'auth.view_permission',])
def sample1(request):
"""Show sample1 page"""
return render(request, 'adminlte2/sample1.html', {})
def sample2(request):
"""Show sample2 page"""
return render(request, 'adminlte2/sample2.html', {})
@login_required()
def demo_css(request):
"""Show examples of extra-features.css"""
return render(request, 'adminlte2/demo_css.html', {
'bootstrap_types': ['primary'],
})
What logged out anonymous users can see and access.

What logged in users without correct permissions can see and access.

What logged in users with correct permissions can see and access.

What logged in superusers can see and access.

Warning
We wanted to prevent the Sample2 view from being accessed by people that do not have at least one permission, but forgot to add that to our view. Because we are using a Loose policy, everyone can see and have access this view. This is the “Loose” part of the loose policy as it defaults to everyone being able to see every view unless a permission is explicitly set on that view to add security.
Let’s fix our mistake so that Sample2 is protected and see the difference.
views.py
Add the missing permission_required_one
decorator to the Sample2 view.
@permission_required_one(['auth.add_permission', 'auth.view_permission',])
def sample2(request):
"""Show sample2 page"""
return render(request, 'adminlte2/sample2.html', {})
What logged out users can see and access now.

What logged in users without correct permissions can see and access now.

What logged in users with correct permissions can see and access now.

What logged in superusers can see and access now.

Strict Decorator Example
In this example there are four routes, views, and sidebar entries.
Home - should be shown to all users regardless of being logged in or having permission. But, we intentionally forgot to add that view’s route to the
ADMINLTE2_STRICT_POLICY_WHITELIST
in order to demonstrate what will happen.Sample 1 - requires two permissions (and thus being logged in) to see and access.
Sample 2 - should require at least one of the listed permissions (and being logged in) to see and access. But, we intentionally forgot to add that permission to demonstrate what will happen.
Demo CSS - requires simply being logged in to see and access.
Note
In the below files, we have purposely made a mistake in regards to the Home and Sample2 views in order to no only demonstrate how the various files and contents work, but also to show what sort of side effects to expect when using the Strict Policy. Below this initial attempt we correct our mistake and show the proper configuration as well as what users will see.
settings.py
# Sidebar menu definition.
ADMINLTE2_MENU = [
{
'text': 'Home',
'links': [
{
'route': 'home',
'text': 'Home',
'icon': 'fa fa-dashboard',
},
{
'route': 'sample1',
'text': 'Sample1',
'icon': 'fa fa-bank'
},
{
'route': 'sample2',
'text': 'Sample2',
'icon': 'fa fa-building'
},
{
'route': 'demo-css',
'text': 'Demo CSS',
'icon': 'fa fa-file'
},
]
},
]
# Ensures that we are using the Strict Policy.
ADMINLTE2_USE_STRICT_POLICY = True
urls.py
urlpatterns = [
path('home/', views.home, name="home"),
path('sample1/', views.sample1, name="sample1"),
path('sample2/', views.sample2, name="sample2"),
path('demo-css/', views.demo_css, name="demo-css"),
]
views.py
from django.shortcuts import render
from django_adminlte_2.decorators import (
login_required,
permission_required,
permission_required_one,
)
def home(request):
"""Show home page"""
return render(request, 'adminlte2/home.html', {})
@permission_required(['auth.add_permission', 'auth.view_permission',])
def sample1(request):
"""Show sample1 page"""
return render(request, 'adminlte2/sample1.html', {})
def sample2(request):
"""Show sample2 page"""
return render(request, 'adminlte2/sample2.html', {})
@login_required()
def demo_css(request):
"""Show examples of extra-features.css"""
return render(request, 'adminlte2/demo_css.html', {
'bootstrap_types': ['primary'],
})
What logged out users can see and access.
Note
As seen in the following screenshots, the route still works and the user can still directly visit and see the Home page despite there not being a sidebar link for it. This is because the Strict policy is only strict at preventing the sidebar menu from rendering links. In order to fully prevent a user from both seeing and directly accessing a view, you must use a decorator on that view.

What logged in users without correct permissions can see and access.

What logged in users with correct perm can see and access.

What logged in superusers can see and access.
Note
Even though we forgot to add the Home route to the whitelist and add permissions to the Sample2 view, the superuser can still see those sidebar entries and has access to those pages as superusers can always see everything.

Warning
We wanted the Home view to be visible and accessible to all people but
as configured, it is not visible to anyone. In addition, the Sample2
page is also not visible to anyone. Because we are using the Strict Policy,
all sidebar menu links are hidden by default. This is the “Strict” part
of the Strict Policy as it defaults to everyone not being able to see every
sidebar menu link unless a permission is explicitly set on that view or the
route for that view is added to the ADMINLTE2_STRICT_POLICY_WHITELIST
.
In the case of the Home view, we are going to add the route to the
ADMINLTE2_STRICT_POLICY_WHITELIST
so that everyone will be able to see
the Home link regardless of their permissions. In the case of
Sample2, we are going to add the missing permissions that we
accidentally omitted.
Let’s fix our mistake so that Home and Sample2 are visible to who they are supposed to be.
settings.py
Add the missing whitelist to the settings file and ensure it includes the home route.
# Lists the routes that do not need permissions to be seen by all users.
ADMINLTE2_STRICT_POLICY_WHITELIST = ['home']
views.py
Add the missing permission_required_one
decorator to the Sample2 view.
@permission_required_one(['auth.add_permission', 'auth.view_permission',])
def sample2(request):
"""Show sample2 page"""
return render(request, 'adminlte2/sample2.html', {})
What logged out users can see and access now.

What logged in users without correct permissions can see and access now.

What logged in users with correct permissions can see and access now.

What logged in superusers can see and access now.

Class Based Views
Mixins
There are two mixins provided by Django-AdminLTE-2 that can be used on a class based view to control whether a user has access to both the view, and the visibility of any links in the sidebar that link to that view. Those decorators are:
Login Required Mixin imported with
from django_adminlte_2.mixins import LoginRequiredMixin
Permission Required Mixin imported with
from django_adminlte_2.mixing import PermissionRequiredMixin
Login Required Mixin
LoginRequiredMixin
This mixin will enforce that a user is logged into the system before they can access the view. Django’s default LoginRequiredMixin is used behind the scenes and is only recreated in this package in order to add the magic of automatic sidebar Link rendering.
When using this mixin on a class based view, if the user in not logged in, the user will not be able to access this view nor will they see a sidebar menu entry that maps to this view. However, if the user is logged in, they will see the sidebar link and have access to the view.
from django_adminlte_2.mixins import LoginRequiredMixin
class DemoCss(LoginRequiredMixin, View):
"""Show examples of extra-features.css"""
def get(request):
return render(request, 'adminlte2/demo_css.html', {
'bootstrap_types': ['primary'],
})
Permission Required Mixin
PermissionRequiredMixin
This mixin will enforce that a user has either all or one of a list of permissions before they can access the view. Django’s default PermissionRequired is used behind the scenes and is only recreated in this package in order to add the magic of automatic sidebar link rendering.
There are two class level attributes used in conjunction with this mixin.
permission_required
or permission_required_one
.
Which one you use is dependent on whether you want to require all permissions
or only one of many permissions for the user to see the sidebar menu link and
have access to the view.
Permission Required Attribute
from django_adminlte_2.mixins import PermissionRequiredMixin
class Sample1(PermissionRequiredMixin, View):
"""Show sample1 page"""
permission_required = [
'auth.add_permission',
'auth.change_permission',
'auth.delete_permission'
]
def get(self, request, *args, **kwargs):
return render(request, 'adminlte2/sample1.html', {})
Permission Required One Attribute
Note
Django does not provide a similar class level attribute by default. This attribute and it’s functionality is exclusive to this package.
Tip
This class level attribute is good when you have a landing page for a section of your site and don’t care whether the user can only read or has full edit permissions. Either one should allow the user to see the sidebar link and gain access to the landing page where further restrictions can be used as needed.
from django_adminlte_2.mixins import PermissionRequiredMixin
class Sample2(PermissionRequiredMixin, View):
"""Show sample2 page"""
permission_required_one = [
'auth.add_permission',
'auth.change_permission',
'auth.delete_permission'
]
def get(self, request, *args, **kwargs):
return render(request, 'adminlte2/sample2.html', {})
Mixin Examples
Loose Mixin Example
In this example there are four routes, views, and sidebar entries.
Home - should be shown to all users regardless of being logged in or having permission.
Sample 1 - requires two permissions (and thus being logged in) to see and access.
Sample 2 - should require at least one of the listed permissions (and being logged in) to see and access. But, we intentionally forgot to add that permission to demonstrate what will happen.
Demo CSS - requires simply being logged in to see and access.
Note
In the below files, we have purposely made a mistake in regards to the Sample2 view in order to no only demonstrate how the various files and contents work, but also to show what sort of side effects to expect when using the Loose Policy. Below this initial attempt we correct our initial mistake and show the proper configuration as well as what users will see.
settings.py
# Sidebar menu definition.
ADMINLTE2_MENU = [
{
'text': 'Home',
'links': [
{
'route': 'home',
'text': 'Home',
'icon': 'fa fa-dashboard',
},
{
'route': 'sample1',
'text': 'Sample1',
'icon': 'fa fa-bank'
},
{
'route': 'sample2',
'text': 'Sample2',
'icon': 'fa fa-building'
},
{
'route': 'demo-css',
'text': 'Demo CSS',
'icon': 'fa fa-file'
},
]
},
]
# Ensures that we are using the Loose Policy.
ADMINLTE2_USE_STRICT_POLICY = False
urls.py
urlpatterns = [
path('home/', views.Home.as_view(), name="home"),
path('sample1/', views.Sample1.as_view(), name="sample1"),
path('sample2/', views.Sample2.as_view(), name="sample2"),
path('demo-css/', views.DemoCss.as_view(),name="demo-css"),
]
views.py
from django.shortcuts import render
from django.views import View
from django_adminlte_2.mixins import (
LoginRequiredMixin,
PermissionRequiredMixin,
)
class Home(View):
"""Show home page"""
def get(self, request, *args, **kwargs):
return render(request, 'adminlte2/home.html', {})
class Sample1(PermissionRequiredMixin, View):
"""Show sample1 page"""
permission_required = ['auth.add_permission', 'auth.view_permission',]
def get(self, request, *args, **kwargs):
return render(request, 'adminlte2/sample1.html', {})
class Sample2(View):
"""Show sample2 page"""
def get(self, request, *args, **kwargs):
return render(request, 'adminlte2/sample2.html', {})
class DemoCss(LoginRequiredMixin, View):
"""Show examples of extra-features.css"""
def get(request):
return render(request, 'adminlte2/demo_css.html', {
'bootstrap_types': ['primary'],
})
What logged out anonymous users can see and access.

What logged in users without correct permissions can see and access.

What logged in users with correct perm can see and access.

What logged in superusers can see and access.

Warning
We wanted to prevent the Sample2 view from being accessed by people that do not have at least one permission, but forgot to add that to our view. Because we are using a Loose policy, everyone can see and have access this view. This is the “Loose” part of the loose policy as it defaults to everyone being able to see every view unless a permission is explicitly set on that view to add security.
Let’s fix our mistake so that Sample2 is protected and see the difference.
views.py
Add the missing PermissionRequiredMixin
mixin and the
permission_required_one
attribute to the Sample2 view.
class Sample2(PermissionRequiredMixin, View):
"""Show sample2 page"""
permission_required_one = [
'auth.add_permission',
'auth.view_permission',
]
def get(self, request, *args, **kwargs):
return render(request, 'adminlte2/sample2.html', {})
What logged out users can see and access now.

What logged in users without correct permissions can see and access now.

What logged in user with correct perms can see and access now.

What logged in superusers can see and access now.

Strict Mixin Example
In this example there are four routes, views, and sidebar entries.
Home - should be shown to all users regardless of being logged in or having permission. But, we intentionally forgot to add that view’s route to the
ADMINLTE2_STRICT_POLICY_WHITELIST
in order to demonstrate what will happen.Sample 1 - requires two permissions (and thus being logged in) to see and access.
Sample 2 - should require at least one of the listed permissions (and being logged in) to see and access. But, we intentionally forgot to add that permission to demonstrate what will happen.
Demo CSS - requires simply being logged in to see and access.
Note
In the below files, we have purposely made a mistake in regards to the Home and Sample2 views in order to no only demonstrate how the various files and contents work, but also to show what sort of side effects to expect when using the Strict Policy. Below this initial attempt we correct our mistake and show the proper configuration as well as what users will see.
settings.py
# Sidebar menu definition.
ADMINLTE2_MENU = [
{
'text': 'Home',
'links': [
{
'route': 'home',
'text': 'Home',
'icon': 'fa fa-dashboard',
},
{
'route': 'sample1',
'text': 'Sample1',
'icon': 'fa fa-bank'
},
{
'route': 'sample2',
'text': 'Sample2',
'icon': 'fa fa-building'
},
{
'route': 'demo-css',
'text': 'Demo CSS',
'icon': 'fa fa-file'
},
]
},
]
# Ensures that we are using the Strict Policy.
ADMINLTE2_USE_STRICT_POLICY = True
urls.py
urlpatterns = [
path('home/', views.Home.as_view(), name="home"),
path('sample1/', views.Sample1.as_view(), name="sample1"),
path('sample2/', views.Sample2.as_view(), name="sample2"),
path('demo-css/', views.DemoCss.as_view(),name="demo-css"),
]
views.py
from django.shortcuts import render
from django.views import View
from django_adminlte_2.mixins import (
LoginRequiredMixin,
PermissionRequiredMixin,
)
class Home(View):
"""Show home page"""
def get(self, request, *args, **kwargs):
return render(request, 'adminlte2/home.html', {})
class Sample1(PermissionRequiredMixin, View):
"""Show sample1 page"""
permission_required = ['auth.add_permission', 'auth.view_permission',]
def get(self, request, *args, **kwargs):
return render(request, 'adminlte2/sample1.html', {})
class Sample2(View):
"""Show sample2 page"""
def get(self, request, *args, **kwargs):
return render(request, 'adminlte2/sample2.html', {})
class DemoCss(LoginRequiredMixin, View):
"""Show examples of extra-features.css"""
def get(request):
return render(request, 'adminlte2/demo_css.html', {
'bootstrap_types': ['primary'],
})
What logged out users can see and access.
Note
As seen in the following screenshots, the route still works and the user can still directly visit and see the Home page despite there not being a sidebar link for it. This is because the Strict mode is only strict at preventing the sidebar menu from rendering links. In order to fully prevent a user from both seeing and directly accessing a view, you must use a decorator on that view.

What logged in users without correct permissions can see and access.

What logged in users with correct perm can see and access.

What logged in superusers can see and access.
Note
Even though we forgot to add the Home route to the whitelist and add permissions to the Sample2 view, the superuser can still see those sidebar entries and has access to those pages as superusers can always see everything.

Warning
We wanted the Home view to be visible and accessible to all people but
as configured, it is not visible to anyone. In addition, the Sample2
page is also not visible to anyone. Because we are using the Strict Policy,
all sidebar menu links are hidden by default. This is the “Strict” part
of the Strict Policy as it defaults to everyone not being able to see every
sidebar menu link unless a permission is explicitly set on that view or the
route for that view is added to the ADMINLTE2_STRICT_POLICY_WHITELIST
.
In the case of the Home view, we are going to add the route to the
ADMINLTE2_STRICT_POLICY_WHITELIST
so that everyone will be able to see
the Home link. In the case of Sample2, we are going to add the
missing permissions that we accidentally omitted.
Let’s fix our mistake so that Home and Sample2 are visible to who they are supposed to be.
settings.py
Add the missing whitelist to the settings file and ensure it includes the home route.
# Lists the routes that do not need permissions to be seen by all users.
ADMINLTE2_STRICT_POLICY_WHITELIST = ['home']
views.py
Add the missing PermissionRequiredMixin
mixin and
permission_required_one
attribute to the Sample2 view.
class Sample2(PermissionRequiredMixin, View):
"""Show sample2 page"""
permission_required_one = [
'auth.add_permission',
'auth.view_permission',
]
def get(self, request, *args, **kwargs):
return render(request, 'adminlte2/sample2.html', {})
What logged out users can see and access now.

What logged in users without correct permissions can see and access now.

What logged in user with correct perms can see and access now.

What logged in superusers can see and access now.
