from django.db import models from django.utils.translation import gettext_lazy as _ from django.core.exceptions import ValidationError <<<<<<< HEAD from dj_category.models import BaseCategoryAbstract class HadisCategory(BaseCategoryAbstract): class SourceType(models.TextChoices): SHIA = 'shia', _('Shia') SUNNI = 'sunni', _('Sunni') class ContentType(models.TextChoices): QURAN = 'quran', _('Quran') HADITH = 'hadith', _('Hadith') class LevelChoices(models.IntegerChoices): LEVEL_1 = 1, _('Level 1 (Root)') LEVEL_2 = 2, _('Level 2 (Child)') LEVEL_3 = 3, _('Level 3 (Grandchild)') source_type = models.CharField(max_length=10, choices=SourceType.choices, default=SourceType.SHIA, verbose_name=_('Source Type'), blank=True) category_type = models.CharField(max_length=10, choices=ContentType.choices, verbose_name=_('Category Content Type'), blank=True, null=True) name = models.CharField(max_length=355, verbose_name=_('name')) order = models.IntegerField(default=0, verbose_name=_('order')) slug = None ======= from mptt.models import MPTTModel, TreeForeignKey from django.utils.text import slugify class HadisSect(models.Model): class SectType(models.TextChoices): SHIA = 'shia', _('Shia') SUNNI = 'sunni', _('Sunni') sect_type = models.CharField(max_length=10, choices=SectType.choices, unique=True, verbose_name=_('Sect Name')) title = models.JSONField(default = list , verbose_name=_('Title')) description = models.JSONField(default = list , verbose_name=_('Description')) is_active = models.BooleanField(default=True, verbose_name=_('Is Active')) order = models.IntegerField(default=0, verbose_name=_('order')) def __str__(self): return f"{self.sect_type}: {self.title[0]['text']}" def get_title(self,lang): """ Get title for a specific language """ if not self.title or not isinstance(self.title, list): return None for tr in self.title: if isinstance(tr, dict) and tr.get('language_code') == lang: return tr.get('text', '') for tr in self.title: if isinstance(tr, dict) and tr.get('language_code') == 'en': return tr.get('text', '') return None def get_description(self,lang): """ Get title for a specific language """ if not self.description or not isinstance(self.description, list): return None for tr in self.description: if isinstance(tr, dict) and tr.get('language_code') == lang: return tr.get('text', '') for tr in self.description: if isinstance(tr, dict) and tr.get('language_code') == 'en': return tr.get('text', '') return None class Meta: verbose_name = _('Hadis Sect') verbose_name_plural = _('Hadis Sects') ordering = ('order',) class HadisCategory(MPTTModel): class SourceType(models.TextChoices): QURAN = 'quran', _('Quran') HADITH = 'hadith', _('Hadith') HISTORY = 'history', _('History') FATWA = 'fatwa', _('Fatwa') QUOTE = 'quote', _('Quote') parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children') sect = models.ForeignKey(HadisSect, on_delete=models.PROTECT, verbose_name=_('Sect'), null=False, blank=False) source_type = models.CharField(max_length=10, choices=SourceType.choices, verbose_name=_('Source Type')) title = models.JSONField(default = list , verbose_name=_('Title')) description = models.JSONField(default = list , verbose_name=_('Description')) order = models.IntegerField(default=0, verbose_name=_('order')) xmind_file = models.FileField(upload_to='hadis/xmind_files/', verbose_name=_('xmind file'), null=True, blank=True) slug = models.SlugField(max_length=255, null=True, blank=True) >>>>>>> develop content_type = None language = None language_id = None <<<<<<< HEAD # This field is not stored in the database, it's only used for the form level_choice = None class Meta: ======= def clean(self): super().clean() if self.parent and self.sect_id != self.parent.sect_id: raise ValidationError( _('Child category must have the same sect_type as its parent. ' f'Parent sect: {self.parent.sect.sect_type}, ' f'Your sect: {self.sect.sect_type}') ) def save(self, *args, **kwargs): self.full_clean() if not self.slug: title = self.title[0]['text'] base_slug = slugify(title, allow_unicode=True) slug = base_slug while HadisCategory.objects.filter(slug=slug).exclude(pk=self.pk).exists(): slug = f"{base_slug}" self.slug = slug super().save(*args, **kwargs) class Meta: indexes = [ models.Index(fields=['parent', 'sect']), models.Index(fields=['sect', 'order']) ] >>>>>>> develop verbose_name = _('Hadis Category') verbose_name_plural = _('Hadis Categories') ordering = ('order',) def __str__(self): <<<<<<< HEAD return f'<{str(self.level_p)}>{self.name}' def __repr__(self): return f'<{str(self.level_p)}>{self.name}' def clean(self): super().clean() # Skip validation for new objects that haven't been saved yet # This allows the admin form to set these values properly if self.pk is None: return # For existing objects, apply the validation rules if self.level_p == 1 and self.category_type: raise ValidationError(_("Level 1 cannot have content type")) if self.level_p == 2 and not self.category_type: raise ValidationError(_("Level 2 must have content type")) if self.level_p == 3 and (self.source_type or self.category_type): raise ValidationError(_("Level 3 cannot have source/content type")) def save(self, *args, **kwargs): self.clean() # Get the level from the parent structure level = self.level_p # Apply level-specific logic # if level == 2 and self.parent: # For level 2, inherit source_type from parent # self.source_type = self.parent.source_type # elif level == 3: # For level 3, inherit both from parent # if self.parent and self.parent.parent: # self.source_type = self.parent.source_type # self.category_type = self.parent.category_type # Call the parent class's save method super().save(*args, **kwargs) @property def level_p(self): if not self.parent: return 1 elif not self.parent.parent: return 2 else: return 3 def get_level_info(self): info = { 'level': self.level_p, 'source_type': None, 'category_type': None, } if self.level_p == 1: info['source_type'] = self.source_type elif self.level_p == 2: info['source_type'] = self.parent.source_type info['category_type'] = self.category_type return info ======= return f"{self.sect.sect_type}: {self.source_type} - {self.title[0]['text']}" def get_title(self,lang): """ Get title for a specific language """ if not self.title or not isinstance(self.title, list): return None for tr in self.title: if isinstance(tr, dict) and tr.get('language_code') == lang: return tr.get('text', '') for tr in self.title: if isinstance(tr, dict) and tr.get('language_code') == 'en': return tr.get('text', '') return None def get_description(self,lang): """ Get title for a specific language """ if not self.description or not isinstance(self.description, list): return None for tr in self.description: if isinstance(tr, dict) and tr.get('language_code') == lang: return tr.get('text', '') for tr in self.description: if isinstance(tr, dict) and tr.get('language_code') == 'en': return tr.get('text', '') return None >>>>>>> develop