forked from ITStudio_OUC/ProgrammeHomework
更新 project-a/articleapp/models.py
This commit is contained in:
@@ -1,9 +1,113 @@
|
|||||||
from django.db import models
|
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):
|
class Article(models.Model):
|
||||||
title = models.CharField(max_length=100)
|
STATUS_CHOICES = (
|
||||||
content = models.TextField()
|
("draft", "草稿"),
|
||||||
create_time = models.DateTimeField(auto_now_add=True)
|
("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):
|
def __str__(self):
|
||||||
return self.title
|
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}
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user