Files
ProgrammeHomework/project-a/articleapp/models.py
T

113 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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):
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}
)