from django.db import models from django.db.models.signals import pre_delete from django.dispatch import receiver from django.conf import settings from django.contrib.auth.models import User class Tag(models.Model): """태그 모델""" name = models.CharField(max_length=50, unique=True) created_at = models.DateTimeField(auto_now_add=True) class Meta: ordering = ['name'] def __str__(self): return self.name class Post(models.Model): title = models.CharField(max_length=255) content = models.TextField() tags = models.ManyToManyField(Tag, related_name='posts', blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) author_id = models.CharField(max_length=150, blank=True, default='') author_name = models.CharField(max_length=150) is_private = models.BooleanField(default=False) # 비공개 여부 (True: 작성자만 볼 수 있음) class Meta: ordering = ['-created_at'] def __str__(self): return self.title class Comment(models.Model): """댓글/대댓글 모델""" post = models.ForeignKey( Post, related_name="comments", on_delete=models.CASCADE ) parent = models.ForeignKey( 'self', null=True, blank=True, related_name="replies", on_delete=models.CASCADE ) # 대댓글 지원 content = models.TextField() author_id = models.CharField(max_length=150, blank=True, default='') author_name = models.CharField(max_length=150) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: ordering = ['created_at'] def __str__(self): return f"Comment by {self.author_name} on {self.post.title}" class Attachment(models.Model): """첨부파일 모델""" post = models.ForeignKey( Post, related_name="attachments", on_delete=models.CASCADE, null=True, blank=True ) # null이면 임시 파일 (아직 게시글에 연결되지 않음) file = models.FileField(upload_to='attachments/%Y/%m/%d/') original_name = models.CharField(max_length=255) # 원본 파일명 file_size = models.PositiveIntegerField() # 파일 크기 (bytes) uploaded_at = models.DateTimeField(auto_now_add=True) uploader_id = models.CharField(max_length=150, blank=True, default='') # 업로더 ID uploader_name = models.CharField(max_length=150, blank=True, default='') # 업로더 이름 batch_id = models.CharField(max_length=36, blank=True, default='') # 업로드 배치 ID (같은 게시글 그룹) def __str__(self): return self.original_name @receiver(pre_delete, sender=Attachment) def delete_attachment_file(sender, instance, **kwargs): """Attachment 삭제 시 MinIO에서 파일도 삭제""" if instance.file: instance.file.delete(save=False)