更新 project-a/articleapp/models.py

This commit is contained in:
2026-10-03 14:07:57 +08:00
parent d322c3b377
commit e5f6a2b113
+107 -3
View File
@@ -1,9 +1,113 @@
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver
import json
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
create_time = models.DateTimeField(auto_now_add=True)
STATUS_CHOICES = (
("draft", "草稿"),
("published", "已发布"),
("archived", "归档"),
)
title = models.CharField(max_length=200, verbose_name="标题")
content = models.TextField(verbose_name="正文")
author = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="作者")
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="draft", verbose_name="状态")
views = models.PositiveIntegerField(default=0, verbose_name="浏览量")
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
is_deleted = models.BooleanField(default=False, verbose_name="是否软删除") # 加分项软删除
def __str__(self):
return self.title
class Meta:
verbose_name = "文章"
verbose_name_plural = "文章"
ordering = ["-created_at"]
class Attachment(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name="attachments", verbose_name="关联文章")
file = models.FileField(upload_to="attachments/", verbose_name="文件")
filename = models.CharField(max_length=200, verbose_name="文件名")
upload_time = models.DateTimeField(auto_now_add=True, verbose_name="上传时间")
downloads = models.PositiveIntegerField(default=0, verbose_name="下载次数") # 加分项下载计数
def __str__(self):
return self.filename
class Meta:
verbose_name = "附件"
verbose_name_plural = "附件"
ordering = ["-upload_time"]
class AuditLog(models.Model):
OP_TYPE_CHOICES = (
("create", "创建"),
("update", "更新"),
("publish", "发布"),
("archive", "归档"),
("delete", "删除"),
)
article = models.ForeignKey(Article, on_delete=models.SET_NULL, null=True, verbose_name="关联文章")
operator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name="操作人")
op_type = models.CharField(max_length=20, choices=OP_TYPE_CHOICES, verbose_name="操作类型")
diff = models.JSONField(default=dict, verbose_name="变更摘要")
time = models.DateTimeField(auto_now_add=True, verbose_name="操作时间")
def __str__(self):
return f"{self.get_op_type_display()} - {self.article}"
class Meta:
verbose_name = "审计日志"
verbose_name_plural = "审计日志"
ordering = ["-time"]
# ========== Django信号:自动生成审计日志(作业硬性要求!禁止在视图手动创建AuditLog) ==========
@receiver(post_save, sender=Article)
def article_post_save(sender, instance, created,** kwargs):
if created:
# 新建文章
AuditLog.objects.create(
article=instance,
operator=instance.author,
op_type="create",
diff={"title": instance.title, "status": instance.status}
)
else:
# 更新文章,记录状态变更
# kwargs里有update_fields,用来拿到改动字段
diff_data = {}
if kwargs.get("update_fields") and "status" in kwargs["update_fields"]:
diff_data["status"] = {"new": instance.status}
if instance.status == "published":
op_type = "publish"
elif instance.status == "archived":
op_type = "archive"
else:
op_type = "update"
else:
op_type = "update"
diff_data["title"] = instance.title
AuditLog.objects.create(
article=instance,
operator=instance.author,
op_type=op_type,
diff=diff_data
)
@receiver(pre_delete, sender=Article)
def article_pre_delete(sender, instance,** kwargs):
# 删除文章前触发信号
AuditLog.objects.create(
article=instance,
operator=instance.author,
op_type="delete",
diff={"title": instance.title}
)