92 lines
3.6 KiB
Python
92 lines
3.6 KiB
Python
import os
|
|
import uuid
|
|
from django.db import models
|
|
from django.core.validators import FileExtensionValidator
|
|
from django.core.exceptions import ValidationError
|
|
|
|
from users.models import User
|
|
from .utils import validate_image_size, validate_video_size, validate_score
|
|
from .managers import PublicationManager
|
|
|
|
ALLOWED_IMAGE_EXTS = ['jpg', 'jpeg', 'png', 'webp', 'gif']
|
|
ALLOWED_VIDEO_EXTS = ['mp4', 'webm', 'mov']
|
|
|
|
def user_directory_path(instance, filename):
|
|
ext = os.path.splitext(filename)[1]
|
|
return f'publications/user_{instance.user.id}/{uuid.uuid4()}{ext}'
|
|
|
|
class Category(models.Model):
|
|
name = models.CharField(max_length=50)
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
# Create your models here.
|
|
class Publication(models.Model):
|
|
class StatusVarioations(models.TextChoices):
|
|
PUBLIC = 'public', 'Public'
|
|
PENDING = 'pending', 'Pending'
|
|
|
|
class ContentVariations(models.TextChoices):
|
|
IMAGE = 'image', 'Image'
|
|
VIDEO = 'video', 'Video'
|
|
|
|
image = models.ImageField(upload_to=user_directory_path, blank=True, null=True, validators=[FileExtensionValidator(ALLOWED_IMAGE_EXTS), validate_image_size])
|
|
video = models.FileField(upload_to=user_directory_path, blank=True, null=True, validators=[FileExtensionValidator(ALLOWED_VIDEO_EXTS), validate_video_size])
|
|
content_type = models.CharField(max_length=20, choices=ContentVariations.choices)
|
|
status = models.CharField(max_length=50, choices=StatusVarioations.choices, default=StatusVarioations.PENDING)
|
|
description = models.CharField(max_length=255)
|
|
is_pinned = models.BooleanField(default=False)
|
|
user = models.ForeignKey(User, on_delete=models.CASCADE, null=False, blank=False)
|
|
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True)
|
|
|
|
time_created = models.DateTimeField(auto_now_add=True)
|
|
time_updated = models.DateTimeField(auto_now=True)
|
|
|
|
objects: PublicationManager["Publication"] = PublicationManager()
|
|
|
|
def __str__(self):
|
|
return f'Content #{self.pk}'
|
|
|
|
def clean(self):
|
|
errors = []
|
|
|
|
if self.content_type == 'image' and not self.image:
|
|
errors.append('Required image file')
|
|
if self.content_type == 'video' and not self.video:
|
|
errors.append('Required video file')
|
|
|
|
if self.image and self.video:
|
|
errors.append('You must upload either a video or an image, not both')
|
|
|
|
if errors:
|
|
raise ValidationError(errors)
|
|
|
|
class Rating(models.Model):
|
|
score = models.IntegerField(validators=[validate_score], null=False)
|
|
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
|
publication = models.ForeignKey(Publication, on_delete=models.CASCADE, related_name="ratings")
|
|
|
|
time_created = models.DateTimeField(auto_now_add=True)
|
|
time_updated = models.DateTimeField(auto_now=True)
|
|
|
|
@staticmethod
|
|
def rate_publication(user: User, publication: Publication, score: int):
|
|
exists_rate = Rating.objects.filter(user=user, publication=publication).first()
|
|
if exists_rate:
|
|
exists_rate.score = score
|
|
exists_rate.save()
|
|
else:
|
|
Rating.objects.create(
|
|
user=user,
|
|
publication=publication,
|
|
score=score
|
|
)
|
|
|
|
class Meta:
|
|
constraints = [
|
|
models.UniqueConstraint(fields=['user', 'publication'], name='unique_user_publication')
|
|
]
|
|
|
|
def __str__(self):
|
|
return f'Score {self.score} by {self.user} for {self.publication}' |