基于 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
。
- 可以接入
? 這個案例展示了一個 完整的企業級權限管理最小可行方案:
- 用戶管理(創建、分配角色)
- 角色管理(組 + 權限)
- 權限管理(模型權限 + 自定義權限)
- 訪問控制(視圖權限校驗)