izaac-2/backend/content/models.py
2025-08-31 23:05:53 +02:00

112 lines
4.3 KiB
Python

#Modele do obsługi treści: takie jak posty, strony, komentarze i przesłane obrazy.
from django.db import models
from users.models import User
from django.conf import settings
from django.utils import timezone
from django.core.validators import FileExtensionValidator
from django.utils.text import slugify
#Obsługa kategorii
class Category(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(unique=True, blank=True)
description = models.TextField(blank=True, null=True)
parent_category = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE, related_name='subcategories')
created_at = models.DateTimeField(auto_now_add=True)
meta_description = models.CharField(max_length=160, blank=True, null=True, help_text="Opis dla wyszukiwarek (SEO)")
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name)
super().save(*args, **kwargs)
def __str__(self):
return self.name
#Obsługa treści
class AbstractContent(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('pending', 'Pending Review'),
('published', 'Published'),
)
title = models.CharField(max_length=255)
slug = models.SlugField(unique=True, blank=True)
content = models.TextField()
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
author = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
category = models.ForeignKey('Category', on_delete=models.CASCADE)
tags = models.ManyToManyField('Tag', blank=True)
meta_title = models.CharField(max_length=70, blank=True, help_text="Tytuł wyświetlany w wyszukiwarkach. Domyślnie będzie użyty title.")
meta_description = models.CharField(max_length=160, blank=True, null=True, help_text="Opis dla wyszukiwarek (SEO)")
meta_image = models.URLField(blank=True, null=True, help_text="Obrazek do podglądu w linkach (np. na Facebooku)")
class Meta:
abstract = True
def __str__(self):
return self.title
#Obsługa postów i stron
class Post(AbstractContent):
pass
class Page(AbstractContent):
pass
#Obsługa komentarzy
class Comment(models.Model):
content = models.TextField(max_length=2000)
approved = models.BooleanField(default=False)
author = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, null=True, blank=True, on_delete=models.CASCADE)
page = models.ForeignKey(Page, null=True, blank=True, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
#Obsługa przesłanych obrazów
class UploadedImage(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
image = models.ImageField(
upload_to='uploads/%Y/%m/%d/',
validators=[FileExtensionValidator(allowed_extensions=['jpg', 'jpeg', 'png', 'gif', 'webp'])]
)
title = models.CharField(max_length=255)
uploaded_at = models.DateTimeField(auto_now_add=True)
file_size = models.PositiveIntegerField() # Size in bytes
category = models.ForeignKey('Category', on_delete=models.CASCADE, default=1)
description = models.TextField(blank=True, null=True, help_text="Opis obrazka")
class Meta:
ordering = ['-uploaded_at']
def __str__(self):
return f"{self.title} - {self.user.username}"
@property
def url(self):
return self.image.url if self.image else None
def save(self, *args, **kwargs):
if not self.file_size and self.image:
self.file_size = self.image.size
super().save(*args, **kwargs)
@classmethod
def get_user_daily_upload_size(cls, user):
today = timezone.now().date()
tomorrow = today + timezone.timedelta(days=1)
return cls.objects.filter(
user=user,
uploaded_at__gte=today,
uploaded_at__lt=tomorrow
).aggregate(total_size=models.Sum('file_size'))['total_size'] or 0
#Obsługa tagów
class Tag(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(unique=True)
def __str__(self):
return self.name