#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