Django RBAC权限实战全流程
基于 Django 内置权限体系(RBAC) 的简单实战案例。
我会从 建模、创建用户、角色和权限、分配权限、接口校验 全流程讲解,既简单又全面。
1️⃣ 项目和应用初始化
pip install django djangorestframework
django-admin startproject myproject
cd myproject
python manage.py startapp accounts
在 settings.py
中注册应用:
INSTALLED_APPS = [...,'rest_framework','accounts','django.contrib.auth','django.contrib.contenttypes',
]
2️⃣ 模型设计(用户、文章示例)
Django 内置的 User 模型已经够用,如果要扩展,可以继承 AbstractUser
:
# accounts/models.py
from django.contrib.auth.models import AbstractUser
from django.db import modelsclass User(AbstractUser):# 可以添加自定义字段phone = models.CharField(max_length=20, blank=True, null=True)class Article(models.Model):title = models.CharField(max_length=255)content = models.TextField()author = models.ForeignKey(User, on_delete=models.CASCADE)class Meta:permissions = [("publish_article", "Can publish article"),("approve_article", "Can approve article"),]def __str__(self):return self.title
# accounts/serializers.py
from rest_framework import serializers
from accounts.models import Articleclass ArticleSerializer(serializers.ModelSerializer):class Meta:model = Articlefields = ['id', 'title', 'content', 'author']read_only_fields = ['author'] # 作者由系统自动指定
然后迁移:
python manage.py makemigrations
python manage.py migrate
3️⃣ 创建用户、组(角色)和权限
在 Django shell 中操作:
python manage.py shell
from django.contrib.auth.models import User, Group, Permission
from accounts.models import Article
from django.contrib.contenttypes.models import ContentType# 创建用户
alice = User.objects.create_user('alice', password='alice123')
bob = User.objects.create_user('bob', password='bob123')# 创建角色(组)
editor_group = Group.objects.create(name='Editor')
admin_group = Group.objects.create(name='Admin')# 给组分配权限
article_ct = ContentType.objects.get_for_model(Article)# Django 模型权限
add_article = Permission.objects.get(codename='add_article', content_type=article_ct)
change_article = Permission.objects.get(codename='change_article', content_type=article_ct)
delete_article = Permission.objects.get(codename='delete_article', content_type=article_ct)
view_article = Permission.objects.get(codename='view_article', content_type=article_ct)# 自定义权限
publish_article = Permission.objects.get(codename='publish_article', content_type=article_ct)# 分配权限给组
editor_group.permissions.add(add_article, change_article, view_article, publish_article)
admin_group.permissions.add(add_article, change_article, delete_article, view_article, publish_article)# 给用户分配组
alice.groups.add(editor_group)
bob.groups.add(admin_group)
4️⃣ 权限校验示例
Django 提供 @permission_required
装饰器和 user.has_perm()
方法。
视图示例
# accounts/views.py
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated, DjangoModelPermissions
from accounts.models import Article
from accounts.serializers import ArticleSerializer
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import statusclass ArticleViewSet(viewsets.ModelViewSet):"""提供文章的 CRUD 接口"""queryset = Article.objects.all()serializer_class = ArticleSerializerpermission_classes = [IsAuthenticated, DjangoModelPermissions]def perform_create(self, serializer):# 自动把当前用户设置为作者serializer.save(author=self.request.user)@action(detail=True, methods=['post'], permission_classes=[IsAuthenticated, DjangoModelPermissions])def publish(self, request, pk=None):"""自定义动作:发布文章需要 'publish_article' 权限"""article = self.get_object()if not request.user.has_perm('accounts.publish_article'):return Response({"detail": "没有权限发布文章"}, status=status.HTTP_403_FORBIDDEN)# 这里可以写发布逻辑,例如设置 published=Truereturn Response({"detail": f"文章 '{article.title}' 已发布"})
5️⃣ URL 配置
# accounts/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ArticleViewSetrouter = DefaultRouter()
router.register(r'articles', ArticleViewSet, basename='article')urlpatterns = [path('', include(router.urls)),
]
这样就自动生成:
-
GET /articles/ → 列表
-
POST /articles/ → 创建
-
GET /articles/{id}/ → 详情
-
PUT /PATCH /articles/{id}/ → 更新
-
DELETE /articles/{id}/ → 删除
-
POST /articles/{id}/publish/ → 自定义发布动作
权限控制说明
DjangoModelPermissions:
自动映射 Django 模型权限到 DRF CRUD 操作:
GET → view_article
POST → add_article
PUT/PATCH → change_article
DELETE → delete_article
自定义动作 publish:
使用 has_perm(‘accounts.publish_article’) 校验自定义权限。
在 myproject/urls.py
中 include:
path('accounts/', include('accounts.urls')),
6️⃣ 核心流程总结
-
用户 → 组(角色) → 权限
- RBAC 模型,简化管理。
-
模型级权限
- Django 自动生成
add/change/delete/view
权限。 - 可自定义权限,如
publish_article
。
- Django 自动生成
-
授权校验
@permission_required
或user.has_perm()
。
-
对象级权限扩展
- 可以接入
django-guardian
或自定义has_object_permission
。
- 可以接入
✅ 这个案例展示了一个 完整的企业级权限管理最小可行方案:
- 用户管理(创建、分配角色)
- 角色管理(组 + 权限)
- 权限管理(模型权限 + 自定义权限)
- 访问控制(视图权限校验)