Skip to main content

ACL

在 Django 中,你可以利用其內建的認證系統、模型管理和中介表來實現 ACL(存取控制列表)和資料的軟刪除功能。以下是如何利用 Django 內建功能實現這些功能的具體步驟:

1. 使用 Django 的認證與授權系統

Django 內建的 auth 應用程式已經包含了對使用者和權限的基本支援。你可以使用內建的 Groups(群組)和 Permissions(權限)來實現 ACL。

(1) 使用者與角色(群組)管理

Django 內建的 User 模型已經包含了使用者資訊,你可以通過 群組 來管理角色。Django 內建的 Permissions 可以直接與模型綁定。

建立群組(角色)並分配權限:

from django.contrib.auth.models import Group, Permission

# 建立角色
admin_group = Group.objects.create(name='admin')
editor_group = Group.objects.create(name='editor')
viewer_group = Group.objects.create(name='viewer')

# 分配權限
delete_permission = Permission.objects.get(codename='delete_article')
edit_permission = Permission.objects.get(codename='change_article')
view_permission = Permission.objects.get(codename='view_article')

# 將權限賦予角色
admin_group.permissions.add(delete_permission, edit_permission, view_permission)
editor_group.permissions.add(edit_permission, view_permission)
viewer_group.permissions.add(view_permission)

(2) 為使用者分配角色

使用 add 方法來將使用者分配到不同的角色:

from django.contrib.auth.models import User

# 查找使用者
alice = User.objects.get(username='Alice')
bob = User.objects.get(username='Bob')
charlie = User.objects.get(username='Charlie')

# 為使用者分配角色
alice.groups.add(admin_group)
bob.groups.add(editor_group)
charlie.groups.add(viewer_group)

2. 設計資源與權限模型

Django 可以自定義模型來表示資源與其權限。你可以擴展模型並使用自訂邏輯進行存取控制。

(1) 資源模型

可以在 Django 中定義 Resource 模型來表示資源(如網頁、API 等)。

from django.db import models

class Resource(models.Model):
name = models.CharField(max_length=255)
resource_type = models.CharField(max_length=255) # e.g., 'page', 'api'

(2) 權限檢查

可以使用 Django 的 has_perm 方法來檢查某個使用者是否有權限進行操作:

user = request.user
if user.has_perm('app.delete_article'):
# 使用者有權限刪除文章
pass
else:
# 沒有權限
pass

3. 軟刪除功能的實現

在 Django 中,可以透過自訂的 deleted_at 欄位來實現軟刪除功能。

(1) 擴展模型

在模型中新增 deleted_at 欄位,並設置軟刪除邏輯。

from django.db import models
from django.utils import timezone

class Article(models.Model):
title = models.CharField(max_length=255)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
deleted_at = models.DateTimeField(null=True, blank=True)

def soft_delete(self):
self.deleted_at = timezone.now()
self.save()

def restore(self):
self.deleted_at = None
self.save()

(2) 篩選未刪除的資料

在查詢中篩選 deleted_at 欄位為 None 的資料:

# 查詢未被刪除的文章
articles = Article.objects.filter(deleted_at__isnull=True)

(3) 刪除與恢復操作

article = Article.objects.get(id=1)
article.soft_delete() # 軟刪除文章
article.restore() # 恢復已刪除文章

4. Django 的信號系統與審計紀錄

可以使用 Django 的信號(signals)來自動記錄刪除行為。例如,當一個文章被刪除時,記錄操作到 logs 表中。

(1) 建立審計紀錄模型

class DeleteLog(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
article = models.ForeignKey(Article, on_delete=models.CASCADE)
reason = models.TextField()
deleted_at = models.DateTimeField(auto_now_add=True)

(2) 使用 post_save 信號記錄刪除操作

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=Article)
def log_delete(sender, instance, **kwargs):
if instance.deleted_at: # 如果文章被軟刪除
DeleteLog.objects.create(user=instance.deleted_by, article=instance, reason='Deleted by user')

總結

Django 提供了豐富的內建功能,能夠快速構建 ACL 和軟刪除系統。你可以利用 Django 的認證與授權系統進行權限控制,通過 deleted_at 欄位實現軟刪除,並使用信號系統進行操作審計。這些功能可以有效地保護資料並控制存取權限,滿足大多數商用網站的需求。