diff --git a/apps/hadis/management/commands/seed_complete_hadis_data.py b/apps/hadis/management/commands/seed_complete_hadis_data.py index 717a280..44b514d 100644 --- a/apps/hadis/management/commands/seed_complete_hadis_data.py +++ b/apps/hadis/management/commands/seed_complete_hadis_data.py @@ -377,30 +377,142 @@ class Command(BaseCommand): self.created_counts['narrator_layers'] = len(self.narrator_layers) def create_reliability_statuses(self): - """Create transmitter reliability statuses""" + """Create transmitter reliability statuses - fixes duplicates first""" + from django.utils.text import slugify + from django.db.models import Count + + # Find and fix duplicate slugs + duplicates = TransmitterReliability.objects.values('slug').annotate( + count=Count('id') + ).filter(count__gt=1) + + for dup in duplicates: + slug_value = dup['slug'] + # Get all records with this slug + records = TransmitterReliability.objects.filter(slug=slug_value) + # Keep the first one, update or delete others + for i, record in enumerate(records): + if i == 0: + continue # Keep first record as is + else: + # Update slug to make it unique + try: + if record.title and isinstance(record.title, list) and len(record.title) > 0: + text = record.title[0].get('text', '').strip() + if text: + new_slug = slugify(text) + else: + from datetime import datetime + new_slug = f"reliability-{datetime.now().strftime('%Y%m%d%H%M%S%f')}-{i}" + else: + from datetime import datetime + new_slug = f"reliability-{datetime.now().strftime('%Y%m%d%H%M%S%f')}-{i}" + except: + from datetime import datetime + new_slug = f"reliability-{datetime.now().strftime('%Y%m%d%H%M%S%f')}-{i}" + + # Ensure uniqueness + counter = 1 + original_slug = new_slug + while TransmitterReliability.objects.filter(slug=new_slug).exclude(pk=record.pk).exists(): + new_slug = f"{original_slug}-{counter}" + counter += 1 + + record.slug = new_slug + record.save(update_fields=['slug']) + self.stdout.write(f"Fixed duplicate reliability slug: {new_slug}") + + # Now create or get reliability statuses for reliability_data in RUSSIAN_RELIABILITY_LEVELS: - reliability, created = TransmitterReliability.objects.get_or_create( - slug=reliability_data['slug'], - defaults={ - 'title': [{'language_code': 'ru', 'text': reliability_data['title']}], - 'color': reliability_data['color'] - } - ) - self.reliability_statuses.append(reliability) + try: + # Try to get by slug first + reliability = TransmitterReliability.objects.filter(slug=reliability_data['slug']).first() + if reliability: + created = False + else: + # Create new one + reliability = TransmitterReliability.objects.create( + slug=reliability_data['slug'], + title=[{'language_code': 'ru', 'text': reliability_data['title']}], + color=reliability_data['color'] + ) + created = True + + self.reliability_statuses.append(reliability) + except Exception as e: + self.stdout.write(self.style.WARNING( + f"Warning creating reliability status {reliability_data['slug']}: {str(e)}" + )) self.created_counts['reliability_statuses'] = len(self.reliability_statuses) def create_opinion_statuses(self): - """Create opinion statuses""" + """Create opinion statuses - fixes duplicates first""" + from django.utils.text import slugify + from django.db.models import Count + + # Find and fix duplicate slugs + duplicates = OpinionStatus.objects.values('slug').annotate( + count=Count('id') + ).filter(count__gt=1) + + for dup in duplicates: + slug_value = dup['slug'] + # Get all records with this slug + records = OpinionStatus.objects.filter(slug=slug_value) + # Keep the first one, update or delete others + for i, record in enumerate(records): + if i == 0: + continue # Keep first record as is + else: + # Update slug to make it unique + try: + if record.title and isinstance(record.title, list) and len(record.title) > 0: + text = record.title[0].get('text', '').strip() + if text: + new_slug = slugify(text) + else: + from datetime import datetime + new_slug = f"opinion-{datetime.now().strftime('%Y%m%d%H%M%S%f')}-{i}" + else: + from datetime import datetime + new_slug = f"opinion-{datetime.now().strftime('%Y%m%d%H%M%S%f')}-{i}" + except: + from datetime import datetime + new_slug = f"opinion-{datetime.now().strftime('%Y%m%d%H%M%S%f')}-{i}" + + # Ensure uniqueness + counter = 1 + original_slug = new_slug + while OpinionStatus.objects.filter(slug=new_slug).exclude(pk=record.pk).exists(): + new_slug = f"{original_slug}-{counter}" + counter += 1 + + record.slug = new_slug + record.save(update_fields=['slug']) + self.stdout.write(f"Fixed duplicate opinion status slug: {new_slug}") + + # Now create or get opinion statuses for opinion_data in RUSSIAN_OPINION_STATUSES: - opinion_status, created = OpinionStatus.objects.get_or_create( - slug=opinion_data['slug'], - defaults={ - 'title': [{'language_code': 'ru', 'text': opinion_data['title']}], - 'color': opinion_data['color'] - } - ) - self.opinion_statuses.append(opinion_status) + try: + # Try to get by slug first + opinion_status = OpinionStatus.objects.filter(slug=opinion_data['slug']).first() + if opinion_status: + created = False + else: + # Create new one + opinion_status = OpinionStatus.objects.create( + slug=opinion_data['slug'], + title=[{'language_code': 'ru', 'text': opinion_data['title']}], + color=opinion_data['color'] + ) + created = True + + self.opinion_statuses.append(opinion_status) + except Exception as e: + self.stdout.write(self.style.WARNING( + f"Warning creating opinion status {opinion_data['slug']}: {str(e)}" + )) self.created_counts['opinion_statuses'] = len(self.opinion_statuses) diff --git a/apps/hadis/models/transmitter.py b/apps/hadis/models/transmitter.py index 6abb658..323c9ff 100644 --- a/apps/hadis/models/transmitter.py +++ b/apps/hadis/models/transmitter.py @@ -68,7 +68,22 @@ class NarratorLayer(models.Model): def save(self, *args, **kwargs): if not self.slug: - slug = slugify(self.name[0]['text']) + # Try to get text from name field with robust error handling + try: + if self.name and isinstance(self.name, list) and len(self.name) > 0: + text = self.name[0].get('text', '').strip() + if text: + slug = slugify(text) + else: + # Fallback to layer number if text is empty + slug = f"layer-{self.number}" + else: + # Fallback to layer number if name structure is invalid + slug = f"layer-{self.number}" + except (IndexError, KeyError, AttributeError, TypeError): + # Fallback to layer number on any error + slug = f"layer-{self.number}" + self.slug = slug super().save(*args, **kwargs) @@ -89,7 +104,23 @@ class TransmitterReliability(models.Model): def save(self, *args, **kwargs): if not self.slug: - slug = slugify(self.title[0]['text']) + # Try to get text from title field with robust error handling + try: + if self.title and isinstance(self.title, list) and len(self.title) > 0: + text = self.title[0].get('text', '').strip() + if text: + slug = slugify(text) + else: + # Fallback to a timestamp-based slug + from datetime import datetime + slug = f"reliability-{datetime.now().strftime('%Y%m%d%H%M%S%f')}" + else: + from datetime import datetime + slug = f"reliability-{datetime.now().strftime('%Y%m%d%H%M%S%f')}" + except (IndexError, KeyError, AttributeError, TypeError): + from datetime import datetime + slug = f"reliability-{datetime.now().strftime('%Y%m%d%H%M%S%f')}" + self.slug = slug super().save(*args, **kwargs) @@ -344,7 +375,23 @@ class OpinionStatus(models.Model): def save(self, *args, **kwargs): if not self.slug: - slug = slugify(self.title[0]['text']) + # Try to get text from title field with robust error handling + try: + if self.title and isinstance(self.title, list) and len(self.title) > 0: + text = self.title[0].get('text', '').strip() + if text: + slug = slugify(text) + else: + # Fallback to a timestamp-based slug + from datetime import datetime + slug = f"opinion-{datetime.now().strftime('%Y%m%d%H%M%S%f')}" + else: + from datetime import datetime + slug = f"opinion-{datetime.now().strftime('%Y%m%d%H%M%S%f')}" + except (IndexError, KeyError, AttributeError, TypeError): + from datetime import datetime + slug = f"opinion-{datetime.now().strftime('%Y%m%d%H%M%S%f')}" + self.slug = slug super().save(*args, **kwargs)