如何用django实现权限控制 (django认证和权限使用条件)

假如我有普通工作员、公司领导、员工管理员、通讯录管理员、文章发布员、文章审计员、文章管理员等员工身份。文章分为普通文章和高级文章,普通文章所有人可以见,高级文章只能公司领导可以看见;文章发布员既可以是普通员工也是可以是公司领导;文章审计员为特定人员,文章发表必须由普通员工或者公司领导发布后,文章审计员统一后,文章才可以正式发布。

在应用中models.py的文件,用于定义文章、用户权限:

from django.contrib.auth.models import Group, Permission
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.contrib import messages
from .models import UserGroup, UserPermission
from django.contrib.auth.models import Group, Permission
from django.http import HttpResponseForbidden, JsonResponse
from django.urls import reverse_lazy
import json


class Article(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    is_published = models.BooleanField(default=False)
    author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    avatar = models.ImageField(upload_to='avatars/')
    phone = models.CharField(max_length=20)
    email = models.EmailField()
    article_type = models.IntegerField() #普通文章或高级文章
    can_see_all = models.BooleanField(default=True) #所有人可见或只有公司领导可见
    ctype = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField() #普通文章或高级文章的id字段
    content_object = GenericForeignKey('ctype', 'object_id') #通用外键关联普通文章表或高级文章表中的id字段

class UserGroup(models.Model):
    name = models.CharField(max_length=50)
    description = models.TextField()

class UserPermission(models.Model):
    user_group = models.ForeignKey(UserGroup, on_delete=models.CASCADE)
    permission = models.ForeignKey(Permission, on_delete=models.CASCADE)
    can_add = models.BooleanField(default=False) #是否可以添加联系人信息到通讯录中
    can_change = models.BooleanField(default=False) #是否可以修改通讯录中的联系人信息
# 在Django自带权限表结构中添加新的权限字段,
# 例如:can_see_article、can_edit_article等。具体操作可参考Django官方文档。

上面是个开胃菜~。~

django权限管理教学,django前后端权限控制

from django.contrib.auth.models import AbstractUser, Group, Permission
from django.db import models
# 定义用户模型
class User(AbstractUser):
# 添加用户角色字段
roles = models.ManyToManyField(Group, related_name='users')
def __str__(self):
return self.username
# 定义角色模型
class Role(models.Model):
name = models.CharField(max_length=50, unique=True)
permissions = models.ManyToManyField(Permission, related_name='roles')
def __str__(self):
return self.name
# 定义文章模型
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
# 定义通讯录模型
class Contact(models.Model):
name = models.CharField(max_length=50)
phone_number = models.CharField(max_length=20)
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.name
# 创建权限组
def create_permission_groups():
# 创建普通员工组
ordinary_employee_group, _ = Group.objects.get_or_create(name='Ordinary Employee')
# 创建公司领导组
company_leader_group, _ = Group.objects.get_or_create(name='Company Leader')
# 创建员工管理员组
employee_admin_group, _ = Group.objects.get_or_create(name='Employee Admin')
# 创建通讯录管理员组
contact_admin_group, _ = Group.objects.get_or_create(name='Contact Admin')
# 创建文章发布员组
article_publisher_group, _ = Group.objects.get_or_create(name='Article Publisher')
# 创建文章审计员组
article_auditor_group, _ = Group.objects.get_or_create(name='Article Auditor')
# 创建文章管理员组
article_admin_group, _ = Group.objects.get_or_create(name='Article Admin')
# 给各个组分配相应的权限
ordinary_employee_group.permissions.add(
# 查看通讯录
Permission.objects.get(codename='view_contact'),
# 查看普通文章
Permission.objects.get(codename='view_article'),
)
company_leader_group.permissions.add(
# 查看通讯录
Permission.objects.get(codename='view_contact'),
# 查看普通文章
Permission.objects.get(codename='view_article'),
# 查看高级文章
Permission.objects.get(codename='view_advanced_article'),
)
employee_admin_group.permissions.add(
# 查看通讯录
Permission.objects.get(codename='view_contact'),
# 添加、修改通讯录
Permission.objects.get(codename='add_contact'),
Permission.objects.get(codename='change_contact'),
)
contact_admin_group.permissions.add(
# 添加、修改通讯录
Permission.objects.get(codename='add_contact'),
Permission.objects.get(codename='change_contact'),
)
article_publisher_group.permissions.add(
# 发布文章
Permission.objects.get(codename='add_article'),
)
article_auditor_group.permissions.add(
# 审核文章
Permission.objects.get(codename='audit_article'),
)
article_admin_group.permissions.add(
# 添加、修改文章
Permission.objects.get(codename='add_article'),
Permission.objects.get(codename='change_article'),
# 审核文章
Permission.objects.get(codename='audit_article'),
)
# 创建权限组及权限
create_permission_groups()

上面的代码定义了用户模型User,角色模型Role,文章模型Article以及通讯录模型Contact。其中,用户模型继承了Django自带的AbstractUser,并添加了一个roles字段用于存储用户角色。角色模型包含角色名称和关联的权限集合,文章和通讯录模型分别关联了创建者(用户模型)。

在create_permission_groups函数中,我们创建了各个角色组,并为不同角色组分配了相应的权限。例如,普通员工组和公司领导组都被授予了查看通讯录和查看普通文章的权限,而公司领导组另外还被授予了查看高级文章的权限。其他角色组的权限也根据需求进行了分配。

需要注意的是,上述代码仅仅是为了演示如何使用Django自带的权限系统来实现角色与权限的管理,并未涉及到具体的视图和路由。在实际项目中,你需要根据具体需求在视图和路由中使用相应的权限来限制用户的访问和操作。

真正的结合Django自带框架的权限管理,参考代码如下:

from django.contrib.auth.models import User, Group, Permission
from django.contrib.contenttypes.models import ContentType

# 创建组
group_employee = Group.objects.create(name='Employee')
group_manager = Group.objects.create(name='Manager')
group_admin = Group.objects.create(name='Admin')

# 创建用户
user_employee = User.objects.create_user(username='employee', password='password')
user_manager = User.objects.create_user(username='manager', password='password')
user_admin = User.objects.create_user(username='admin', password='password')

# 将用户添加到组
user_employee.groups.add(group_employee)
user_manager.groups.add(group_manager)
user_admin.groups.add(group_admin)

# 创建权限
content_type = ContentType.objects.get_for_model(User)

# 普通文章权限
perm_view_article = Permission.objects.create(
    codename='view_article',
    name='Can view article',
    content_type=content_type,
)
group_employee.permissions.add(perm_view_article)

# 高级文章权限
perm_view_advanced_article = Permission.objects.create(
    codename='view_advanced_article',
    name='Can view advanced article',
    content_type=content_type,
)
group_manager.permissions.add(perm_view_advanced_article)

# 公司通讯录权限
perm_view_contact = Permission.objects.create(
    codename='view_contact',
    name='Can view contact',
    content_type=content_type,
)
group_employee.permissions.add(perm_view_contact)
group_manager.permissions.add(perm_view_contact)

perm_edit_contact = Permission.objects.create(
    codename='edit_contact',
    name='Can edit contact',
    content_type=content_type,
)
group_admin.permissions.add(perm_edit_contact)

# 文章发布权限
perm_publish_article = Permission.objects.create(
    codename='publish_article',
    name='Can publish article',
    content_type=content_type,
)
group_employee.permissions.add(perm_publish_article)
group_manager.permissions.add(perm_publish_article)

# 文章审计权限
perm_audit_article = Permission.objects.create(
    codename='audit_article',
    name='Can audit article',
    content_type=content_type,
)
group_admin.permissions.add(perm_audit_article)

# 示例用法
if user_employee.has_perm('view_article'):
    print('Employee can view article')

if user_manager.has_perm('view_advanced_article'):
    print('Manager can view advanced article')

if user_employee.has_perm('view_contact'):
    print('Employee can view contact')

if user_admin.has_perm('edit_contact'):
    print('Admin can edit contact')

if user_employee.has_perm('publish_article'):
    print('Employee can publish article')

if user_manager.has_perm('publish_article'):
    print('Manager can publish article')

if user_admin.has_perm('audit_article'):
    print('Admin can audit article')

以上示例代码中,我们使用Group模型来创建不同角色的组,并使用User模型创建相应的用户。然后,我们使用Permission模型来创建不同的权限,并将权限分配给相应的组。最后,我们通过has_perm方法来检查用户是否拥有某个权限。

方法二:

# models.py

from django.contrib.auth.models import AbstractUser
from django.db import models

class User(AbstractUser):
    is_employee = models.BooleanField(default=False)  # 是否为普通员工
    is_leader = models.BooleanField(default=False)  # 是否为公司领导
    is_contact_admin = models.BooleanField(default=False)  # 是否为通讯录管理员
    is_article_publisher = models.BooleanField(default=False)  # 是否为文章发布员
    is_article_auditor = models.BooleanField(default=False)  # 是否为文章审计员

class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    is_advanced = models.BooleanField(default=False)  # 是否为高级文章

# views.py

from django.contrib.auth.decorators import login_required
from django.contrib.auth.decorators import user_passes_test
from django.shortcuts import render

@login_required
def view_contact(request):
    if request.user.is_employee:
        # 普通员工可以查看公司通讯录
        # TODO: 返回通讯录页面
        pass

@login_required
@user_passes_test(lambda u: u.is_employee or u.is_leader)
def view_article(request, article_id):
    article = Article.objects.get(id=article_id)
    if article.is_advanced and not request.user.is_leader:
        # 高级文章只能公司领导可以查看
        # TODO: 返回没有权限查看高级文章的提示页面
        pass
    else:
        # TODO: 返回文章内容页面
        pass

@login_required
@user_passes_test(lambda u: u.is_contact_admin)
def edit_contact(request):
    # 通讯录管理员可以发布、修改通讯录的姓名、电话号码等内容
    # TODO: 返回通讯录编辑页面
    pass

@login_required
@user_passes_test(lambda u: u.is_employee or u.is_leader)
def publish_article(request):
    if request.method == 'POST':
        title = request.POST['title']
        content = request.POST['content']
        is_advanced = request.POST.get('is_advanced', False)
        article = Article.objects.create(title=title, content=content, is_advanced=is_advanced)
        if not request.user.is_employee:
            # 文章发布员是公司领导,直接发布文章
            # TODO: 返回文章发布成功页面
            pass
        else:
            # 普通员工发布文章后需要等待审计员审核
            # TODO: 返回文章等待审核页面
            pass

@login_required
@user_passes_test(lambda u: u.is_article_auditor)
def audit_article(request, article_id):
    article = Article.objects.get(id=article_id)
    # TODO: 审核文章逻辑
    pass

以上代码演示了如何在Django中使用自带的权限表结构来实现上述员工身份权限控制的功能。通过修改用户模型,并结合user_passes_test装饰器,可以实现不同身份的用户访问不同的视图函数。在视图函数中根据用户的身份和权限进行相应的逻辑处理。