import os from autoslug import AutoSlugField from django.conf import settings from django.core.files.base import ContentFile from django.db import models from imagekit.models import ProcessedImageField from tinymce.models import HTMLField from core.utils import image_optimizer # Create your models here. class Category(models.Model): aktif = ( (True, 'Evet'), (False, 'Hayır'), ) title = models.CharField(max_length=254, verbose_name="Kategori") keywords = models.CharField(max_length=254, verbose_name="Seo Kelimeleri Aralarına Virgül Koyunuz") description = models.CharField(max_length=254, verbose_name="Açıklama") created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi") updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi") is_active = models.BooleanField(default=True, verbose_name='Yayındamı', choices=aktif) order = models.IntegerField(verbose_name='Görüntülenme Sırası', default=1, db_index=True) slug = AutoSlugField(populate_from='title', null=False, unique=True, editable=True, db_index=True, max_length=250, blank=True) parent = models.ForeignKey('self', related_name='child', on_delete=models.CASCADE, blank=True, null=True, verbose_name='Üst Kategorisi') image = ProcessedImageField(**image_optimizer('uploads/category', 300, 300, 85, 'PNG'), verbose_name='Resim 630 x 653 Olmali ve Transparan PNG Olmali', blank=True, null=True) class Meta: ordering = ["order"] db_table = 'categories' verbose_name_plural = "Post Kategorilerileri" verbose_name = "Post Kategori" unique_together = ('slug', 'parent',) def get_slug(self): slug = self.title.replace('ı', "i").replace('İ', 'i') number = 1 while Category.objects.filter(slug=slug).exists(): slug = '{}-{}'.format(slug, number) number += 1 return slug def save(self, *args, **kwargs): if not self.slug: self.slug = self.get_slug() super().save(*args, **kwargs) def __str__(self): full_path = [self.title] k = self.parent while k is not None: full_path.append(k.title) k = k.parent return ' -> '.join(full_path[::-1]) class Tags(models.Model): aktif = ( (True, 'Evet'), (False, 'Hayır'), ) tag = models.CharField(max_length=254, verbose_name="Post Tagları") slug = AutoSlugField(populate_from='tag', null=False, unique=True, editable=True, db_index=True, max_length=250, blank=True) created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi") updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi") is_active = models.BooleanField(default=True, verbose_name='Yayındamı', choices=aktif) class Meta: ordering = ["-created_at"] db_table = 'tags' verbose_name_plural = "Post Tagları" verbose_name = "Post Tagı" def get_slug(self): slug = self.tag.replace('ı', "i").replace('İ', 'i') number = 1 while Tags.objects.filter(slug=slug).exists(): slug = '{}-{}'.format(slug, number) number += 1 return slug def save(self, *args, **kwargs): if not self.slug: self.slug = self.get_slug() super().save(*args, **kwargs) def __str__(self): return self.tag class Post(models.Model): aktif = ( (True, 'Evet'), (False, 'Hayır'), ) title = models.CharField(max_length=254, verbose_name="Post Başlığı") user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='posts', null=True, blank=True) content = HTMLField(blank=True, null=True, verbose_name='Post İçeriği') categories = models.ManyToManyField(Category, verbose_name="Post Kategorisi", related_name='c_categories') keywords = models.CharField(max_length=254, verbose_name="Seo Kelimeleri Aralarına Virgül Koyunuz") tags = models.ManyToManyField(Tags, verbose_name="Post Tagları", related_name='tags') image = ProcessedImageField(**image_optimizer('uploads/post', 840, 500, 85, 'avif'), null=True, blank=True) thumb = ProcessedImageField(**image_optimizer('uploads/post/thumb', 348, 160, 85, 'avif'), null=True, blank=True,editable=False) video = models.CharField(verbose_name="Video", null=True, blank=True, max_length=254, default='none') slug = AutoSlugField(populate_from='title', null=False, unique=True, editable=True, db_index=True, max_length=250, blank=True) created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi") updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi") is_active = models.BooleanField(default=True, verbose_name='Yayındamı ?', choices=aktif) is_front = models.BooleanField(default=True, verbose_name='Önde Görünsünmü ?', choices=aktif) parent = models.ForeignKey('self', related_name='child', on_delete=models.CASCADE, blank=True, null=True, editable=False, verbose_name='Konular') class Meta: ordering = ["created_at"] db_table = 'posts' verbose_name_plural = "Posts" verbose_name = "Post" unique_together = ('slug',) def get_slug(self): slug = self.title.replace('ı', "i").replace('İ', 'i') number = 1 while Post.objects.filter(slug=slug).exists(): slug = '{}-{}'.format(slug, number) number += 1 return slug def save(self, *args, **kwargs): if not self.slug: self.slug = self.get_slug() if self.image: # Eğer yeni bir kayıt ise veya resim değişmişse update_thumb = False if not self.pk: update_thumb = True else: try: old_instance = self.__class__.objects.get(pk=self.pk) if self.image != old_instance.image: update_thumb = True except self.__class__.DoesNotExist: pass if update_thumb: try: if hasattr(self.image, 'closed') and self.image.closed: self.image.open() if hasattr(self.image, 'seek'): self.image.seek(0) content = self.image.read() filename = os.path.basename(self.image.name) # Doğrudan alana ata, super().save() işleyecek self.thumb = ContentFile(content, name=filename) except Exception: pass finally: if hasattr(self.image, 'seek'): self.image.seek(0) super().save(*args, **kwargs) def __str__(self): return f"Postlar: {self.title}" class CategoryView(models.Model): """Kategori ziyaretlerini takip etmek için model""" category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='category_views') ip_address = models.GenericIPAddressField(verbose_name='IP Adresi') user_agent = models.TextField(blank=True, null=True, verbose_name='User Agent') created_at = models.DateTimeField(auto_now_add=True, verbose_name='Ziyaret Tarihi') class Meta: db_table = 'category_views' verbose_name = 'Kategori Ziyareti' verbose_name_plural = 'Kategori Ziyaretleri' # unique_together kısıtlamasını kaldırdık - artık günlük bazda kontrol edeceğiz indexes = [ models.Index(fields=['category', 'ip_address', 'created_at']), ] def __str__(self): return f"{self.category.title} - {self.ip_address} - {self.created_at.strftime('%Y-%m-%d %H:%M')}" class Comment(models.Model): aktif = ( (True, 'Evet'), (False, 'Hayır'), ) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='cuser') product = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='_product') title = models.CharField(max_length=254, verbose_name="Yorum Başlığı") body = models.TextField(verbose_name='Yorum') created_at = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="Oluşturulma Tarihi") updated_at = models.DateTimeField(auto_now=True, editable=False, verbose_name="Güncelleme Tarihi") is_active = models.BooleanField(default=True, verbose_name='Yayındamı', choices=aktif) slug = AutoSlugField(populate_from='title', null=False, unique=True, editable=False, db_index=True) parent = models.ForeignKey('self', related_name='child', on_delete=models.CASCADE, blank=True, null=True) class Meta: ordering = ["-created_at"] db_table = 'comments' verbose_name_plural = "Post Yorumları" verbose_name = "Post Yorum" unique_together = ('slug', 'parent',) def get_slug(self): slug = self.title.replace('ı', "i").replace('İ', 'i') number = 1 while Comment.objects.filter(slug=slug).exists(): slug = '{}-{}'.format(slug, number) number += 1 return slug def save(self, *args, **kwargs): if not self.slug: self.slug = self.get_slug() super().save(*args, **kwargs) def __str__(self): full_path = [self.title] k = self.parent while k is not None: full_path.append(k.title) k = k.parent return ' -> '.join(full_path[::-1])