Browse Source

relatives and details of narrators updated

master
Mohsen Taba 3 weeks ago
parent
commit
e4bcb9bd3b
  1. 28
      apps/hadis/migrations/0025_transmitters_companion_type_transmitters_ikhtilat_and_more.py
  2. 31
      apps/hadis/migrations/0026_transmitterrelative.py
  3. 44
      apps/hadis/models/transmitter.py
  4. 37
      apps/hadis/serializers/hadis.py

28
apps/hadis/migrations/0025_transmitters_companion_type_transmitters_ikhtilat_and_more.py

@ -0,0 +1,28 @@
# Generated by Django 5.2.12 on 2026-06-28 13:52
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('hadis', '0024_hadiscorrection_links_hadisinterpretation_links'),
]
operations = [
migrations.AddField(
model_name='transmitters',
name='companion_type',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Companion Type'),
),
migrations.AddField(
model_name='transmitters',
name='ikhtilat',
field=models.BooleanField(default=False, verbose_name='Ikhtilat'),
),
migrations.AddField(
model_name='transmitters',
name='tadlis',
field=models.BooleanField(default=False, verbose_name='Tadlis'),
),
]

31
apps/hadis/migrations/0026_transmitterrelative.py

@ -0,0 +1,31 @@
# Generated by Django 5.2.12 on 2026-06-28 13:58
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('hadis', '0025_transmitters_companion_type_transmitters_ikhtilat_and_more'),
]
operations = [
migrations.CreateModel(
name='TransmitterRelative',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('relation_type', models.CharField(choices=[('father', 'Father'), ('son', 'Son')], max_length=50, verbose_name='Relation Type')),
('name', models.CharField(max_length=255, verbose_name='Name')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='updated at')),
('narrator', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='relative_of', to='hadis.transmitters', verbose_name='Narrator')),
('related_to', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='relatives', to='hadis.transmitters', verbose_name='Related To')),
],
options={
'verbose_name': 'Transmitter Relative',
'verbose_name_plural': 'Transmitter Relatives',
'ordering': ['relation_type', 'name'],
},
),
]

44
apps/hadis/models/transmitter.py

@ -258,6 +258,12 @@ class Transmitters(models.Model):
death_year_hijri = models.CharField(max_length=50, verbose_name=_("Death Year (Hijri)"), null=True, blank=True) death_year_hijri = models.CharField(max_length=50, verbose_name=_("Death Year (Hijri)"), null=True, blank=True)
age_at_death = models.PositiveIntegerField(verbose_name=_('Age at Death'), blank=True, null=True) age_at_death = models.PositiveIntegerField(verbose_name=_('Age at Death'), blank=True, null=True)
generation = models.PositiveIntegerField(verbose_name=_('Generation'), blank=True, null=True) generation = models.PositiveIntegerField(verbose_name=_('Generation'), blank=True, null=True)
# New fields
tadlis = models.BooleanField(default=False, verbose_name=_('Tadlis'))
ikhtilat = models.BooleanField(default=False, verbose_name=_('Ikhtilat'))
companion_type = models.CharField(max_length=255, null=True, blank=True, verbose_name=_('Companion Type'))
# Religious & Academic Information # Religious & Academic Information
reliability = models.ForeignKey( reliability = models.ForeignKey(
TransmitterReliability, TransmitterReliability,
@ -790,3 +796,41 @@ class OriginalTextReferenceImage(models.Model):
reference = models.ForeignKey(OriginalTextReference, related_name='images', on_delete=models.CASCADE) reference = models.ForeignKey(OriginalTextReference, related_name='images', on_delete=models.CASCADE)
image = models.ImageField(upload_to='hadis/original_text_images/') image = models.ImageField(upload_to='hadis/original_text_images/')
priority = models.IntegerField(default=0) priority = models.IntegerField(default=0)
class TransmitterRelative(models.Model):
class RelationTypeChoices(models.TextChoices):
FATHER = 'father', _('Father')
SON = 'son', _('Son')
related_to = models.ForeignKey(
Transmitters,
on_delete=models.CASCADE,
verbose_name=_('Related To'),
related_name='relatives'
)
relation_type = models.CharField(
max_length=50,
choices=RelationTypeChoices.choices,
verbose_name=_('Relation Type')
)
name = models.CharField(max_length=255, verbose_name=_('Name'))
narrator = models.ForeignKey(
Transmitters,
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name=_('Narrator'),
related_name='relative_of'
)
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_('created at'))
updated_at = models.DateTimeField(auto_now=True, verbose_name=_('updated at'))
class Meta:
verbose_name = _('Transmitter Relative')
verbose_name_plural = _('Transmitter Relatives')
ordering = ['relation_type', 'name']
def __str__(self):
return f"{self.name} ({self.get_relation_type_display()} of {self.related_to})"

37
apps/hadis/serializers/hadis.py

@ -446,6 +446,7 @@ class TransmitterDetailSerializer(serializers.ModelSerializer):
died_in = LocalizedField() died_in = LocalizedField()
description = LocalizedField() description = LocalizedField()
reliability = serializers.SerializerMethodField() reliability = serializers.SerializerMethodField()
relatives = serializers.SerializerMethodField()
share_link = serializers.CharField(read_only=True) share_link = serializers.CharField(read_only=True)
class Meta: class Meta:
@ -456,7 +457,8 @@ class TransmitterDetailSerializer(serializers.ModelSerializer):
'lived_in','died_in','birth_year_hijri', 'lived_in','died_in','birth_year_hijri',
'death_year_hijri','age_at_death','reliability', 'death_year_hijri','age_at_death','reliability',
'madhhab',"in_sahih_muslim","in_sahih_bukhari", 'madhhab',"in_sahih_muslim","in_sahih_bukhari",
"description",'generation','share_link'
"description",'generation','share_link',
'tadlis', 'ikhtilat', 'companion_type', 'relatives'
] ]
def get_reliability(self, obj): def get_reliability(self, obj):
@ -470,6 +472,39 @@ class TransmitterDetailSerializer(serializers.ModelSerializer):
} }
return None return None
def get_relatives(self, obj):
relatives_qs = obj.relatives.all()
grouped = {}
for rel in relatives_qs:
rel_type = rel.relation_type
slug = rel.narrator.slug if rel.narrator else None
# Use narrator's localized name if exists and name is empty, otherwise use the direct name
name = rel.name
if rel.narrator and not name:
request = self.context.get('request')
name = get_localized_text(rel.narrator.full_name, request)
item = {
"name": name,
"slug": slug
}
if rel_type not in grouped:
grouped[rel_type] = []
grouped[rel_type].append(item)
result = []
for rel_type, items in grouped.items():
if rel_type == 'father' and items:
result.append({"father": items[0]})
else:
result.append({rel_type: items})
return result
class TransmittersFiltersSerializer(serializers.ModelSerializer): class TransmittersFiltersSerializer(serializers.ModelSerializer):
pass pass

Loading…
Cancel
Save