为了实现 Django 权限认证,我们需要做以下几个步骤:
- 开启认证系统
在 Django 项目中,我们需要启用认证系统,以便实现权限认证。在 settings.py
文件中,需添加以下代码:
INSTALLED_APPS = [
...
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
]
此外,我们还需在项目路由中引入 auth 的 URLconf,并保证登录和注销链接都能正确调用。
- 定义用户类型
我们需要根据用户类型来设置用户的访问和显示权限。在 Django 认证系统中,用户类型通常是指用户的权限级别,其中超级管理员具有最高权限级别。
在 models.py
中,我们可以定义 UserType 模型,以保存不同用户类型:
class UserType(models.Model):
name = models.CharField(max_length=32, verbose_name='用户类型名称')
is_admin = models.BooleanField(default=False, verbose_name='是否为管理员')
class Meta:
verbose_name = '用户类型'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
以上代码定义的 UserType 模型包含两个字段:name 和 is_admin。is_admin 字段表示当前用户是否为管理员。我们可以将 is_admin 设为布尔类型,以便后续验证用户是否为管理员。
- 自定义认证后端
根据 Django 原生认证系统的思路,我们需要自定义认证后端,以便在用户登录时验证用户是否为管理员,并根据用户类型设置用户的访问和显示权限。
在 backend.py
中,我们需要实现一下方法:
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from django.db.models import Q
User = get_user_model()
class CustomBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = User.objects.get(Q(username=username) | Q(email=username))
if user.is_active and user.check_password(password):
return user
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
def has_perm(self, user_obj, perm, obj=None):
if user_obj.is_superuser:
return True
if user_obj.user_type.is_admin == True:
return True
return False
def has_module_perms(self, user_obj, app_label):
if user_obj.is_superuser:
return True
if user_obj.user_type.is_admin == True:
return True
return False
以上代码的功能如下:
- authenticate 方法用于验证用户是否存在,用户名和密码是否正确。
- get_user 方法用于获取用户对象。
- has_perm 方法用于验证用户是否具有访问权限,其中 user_obj 为用户对象,perm 表示权限名称,obj 表示权限作用的模型对象。
-
has_module_perms 方法用于验证用户是否具有访问指定模块的权限,其中 app_label 表示应用程序名称。
-
编写视图函数
根据用户类型,我们需要控制不同用户的访问和显示权限。因此,我们需要编写视图函数来处理这些问题。
在 views.py
中,我们需要定义不同用户类别的视图函数:
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/')
def index(request):
user = request.user
if user.is_superuser:
return render(request, 'admin.html')
elif user.user_type.is_admin == True:
return render(request, 'admin.html')
else:
return render(request, 'user.html')
以上代码中的 index 视图函数分为三部分:
- login_required 用于保护当前视图,如果用户未登录,则会自动跳转到登录页面。
- 然后获取当前用户对象,并使用 if 语句对该用户特征进行认证。
-
最后根据用户特征挑选不同的模板进行渲染。
-
定义 URLconf
最后,我们需要定义 URLconf,以在项目中设置 URL 映射路由。
在 urls.py
中,我们可以按照以下方式设置路径映射:
from django.conf.urls import url
from django.contrib import admin
from django.contrib.auth.views import LoginView, LogoutView
from .views import *
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', index, name='index'),
url(r'^login/$', LoginView.as_view(template_name='login.html'), name='login'),
url(r'^logout/$', LogoutView.as_view(next_page='/'), name='logout'),
]
以上代码中,^$ 引用 index 视图函数,即为我们刚刚编写的 index 函数。login 和 logout 则引用 Django 原生的 LoginView 和 LogoutView 视图函数。
示例一:
例如我们现在想要控制首页的访问权限,只有管理员和超级管理员才能访问,我们可以根据以下方法实现:
- 在
models.py
中定义用户类型模型,具体代码如下:
class UserType(models.Model):
name = models.CharField(max_length=32, verbose_name='用户类型名称')
is_admin = models.BooleanField(default=False, verbose_name='是否为管理员')
class Meta:
verbose_name = '用户类型'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
- 在
backend.py
中自定义认证后端,并重载 has_perm 方法。具体代码如下:
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from django.db.models import Q
User = get_user_model()
class CustomBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = User.objects.get(Q(username=username) | Q(email=username))
if user.is_active and user.check_password(password):
return user
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
def has_perm(self, user_obj, perm, obj=None):
if user_obj.is_superuser:
return True
if user_obj.user_type.is_admin == True:
return True
return False
def has_module_perms(self, user_obj, app_label):
if user_obj.is_superuser:
return True
if user_obj.user_type.is_admin == True:
return True
return False
- 在
views.py
中,我们需要定义不同用户类别的视图函数,代码如下:
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/')
def index(request):
user = request.user
if user.is_superuser:
return render(request, 'admin.html')
elif user.user_type.is_admin == True:
return render(request, 'admin.html')
else:
return render(request, 'user.html')
- 在
urls.py
中,我们需要定义首页路由和登录、注销路由,具体代码如下:
from django.conf.urls import url
from django.contrib import admin
from django.contrib.auth.views import LoginView, LogoutView
from .views import *
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', index, name='index'),
url(r'^login/$', LoginView.as_view(template_name='login.html'), name='login'),
url(r'^logout/$', LogoutView.as_view(next_page='/'), name='logout'),
]
以上操作完成后,只有管理员和超级管理员才可以访问首页。如果不是管理员或超级管理员,则会跳转到登录页面。
示例二:
如果我们现在想要控制某些页面的显示权限,可以使用 Django 模板中的宏。例如,我们现在想在管理员页面中添加一个新功能,在超级管理员页面中隐藏该功能,具体方式如下:
在 views.py
中,我们需要定义不同用户类别的视图函数,代码如下:
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/')
def index(request):
user = request.user
if user.is_superuser:
return render(request, 'admin.html', {'is_superuser': True})
elif user.user_type.is_admin == True:
return render(request, 'admin.html', {'is_superuser': False})
else:
return render(request, 'user.html')
在模板文件 admin.html
中,我们将新功能放在一个名为 new_feature
的 div 中,并使用宏控制该 div 是否显示。
{% if is_superuser %}
<div id="new_feature">
<!-- 新功能代码 -->
</div>
{% endif %}
以上代码实现了当用户类型为超级管理员时,新功能的 div 显示,而其他用户则看不到该 div。
最后,在 urls.py
中添加相应的路由即可。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Django 权限认证(根据不同的用户,设置不同的显示和访问权限) - Python技术站