Files
vontor-cz/backend/social/posts/models.py

100 lines
2.9 KiB
Python

from venv import logger
from django.db import models
from django.conf import settings
from vontor_cz.models import SoftDeleteModel
from logging import Logger
logger = Logger(__name__)
try:
import magic
mime = magic.Magic(mime=True)
except ImportError:
logger.warning("python-magic library not found. PostContent MIME type detection will not work.")
magic = None
mime = None
class Post(SoftDeleteModel):
AUTHOR_FIELD = 'author'
content = models.TextField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='posts'
)
hub = models.ForeignKey(
'hubs.Hub',
on_delete=models.CASCADE,
null=True,
blank=True
)
tags = models.ManyToManyField(
'hubs.Tags',
related_name='posts',
blank=True,
)
reply_to = models.ForeignKey(
'self',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='replies'
)
def __str__(self):
return f"Post {self.id}"
class PostContent(SoftDeleteModel):
post = models.ForeignKey(Post, related_name='contents', on_delete=models.CASCADE)
mime_type = models.CharField(max_length=100)
file = models.FileField(upload_to='post_contents/', null=True, blank=True) # For images/videos
alt_text = models.TextField(blank=True, null=True) # For text content
def __str__(self):
return f"Content for Post {self.post.id} - Type: {self.mime_type}"
def save(self, *args, **kwargs):
if self.file and not self.file._committed:
if mime is not None:
data = self.file.read(1024)
self.file.seek(0)
self.mime_type = mime.from_buffer(data)
else:
import mimetypes
content_type = getattr(self.file, 'content_type', None)
self.mime_type = (
content_type
or mimetypes.guess_type(self.file.name)[0]
or 'application/octet-stream'
)
return super().save(*args, **kwargs)
class PostVote(SoftDeleteModel):
class VoteChoice(models.IntegerChoices):
UP = 1, 'Upvote'
DOWN = -1, 'Downvote'
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='votes')
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
vote = models.SmallIntegerField(choices=VoteChoice.choices)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ('post', 'user')
def __str__(self):
label = 'up' if self.vote == self.VoteChoice.UP else 'down'
return f"{self.user} voted {label} on Post {self.post_id}"