Browse Source
feat(hadis): add multi-category M2M support with full backend integration
feat(hadis): add multi-category M2M support with full backend integration
Models: - Hadis: add categories ManyToManyField to HadisCategory (related_name=hadis_items) - Hadis.clean(): validate that none of the M2M categories have subcategories - HadisCategory.clean(): update parent/leaf validation to also check hadis_items Migration: - 0050_hadis_categories: create hadis_categories junction table Serializers (Admin): - AdminHadisDetailSerializer: add categories (PK writable), categories_detail (read-only nested), and categories_paths (full ancestor path per category) - validate_categories(): enforce leaf-only constraint on M2M selection - create/update: sync categories M2M; auto-set FK category from first M2M item - AdminHadisCategoryArchiveDetailSerializer: update child_arguments and child_count to use Q(category|categories) Views (Admin): - AdminHadisCategoryViewSet: annotate has_hadith using Q(category|categories) - AdminHadisViewSet: prefetch categories; filter category_id, collection_id, source_type with Q() + distinct() Views (Public): - HadisListView: filter by category slug across FK and M2M using Q() + distinct() - CategoryHadisCorrectionsView: filter corrections via M2M-aware category_id__in querymaster
7 changed files with 195 additions and 65 deletions
-
35apps/hadis/migrations/0050_hadis_categories.py
-
9apps/hadis/models/category.py
-
7apps/hadis/models/hadis.py
-
78apps/hadis/serializers/hadis.py
-
89apps/hadis/serializers/serializers_admin.py
-
14apps/hadis/views/hadis.py
-
12apps/hadis/views_admin.py
@ -0,0 +1,35 @@ |
|||
# Generated by Django 4.2.30 on 2026-10-13 11:19 |
|||
|
|||
from django.db import migrations, models |
|||
|
|||
|
|||
def populate_categories_from_category(apps, schema_editor): |
|||
Hadis = apps.get_model('hadis', 'Hadis') |
|||
HadisCategoryThrough = Hadis.categories.through |
|||
items_to_create = [] |
|||
for hadis in Hadis.objects.filter(category__isnull=False).only('id', 'category_id'): |
|||
items_to_create.append( |
|||
HadisCategoryThrough(hadis_id=hadis.id, hadiscategory_id=hadis.category_id) |
|||
) |
|||
if items_to_create: |
|||
HadisCategoryThrough.objects.bulk_create(items_to_create, ignore_conflicts=True) |
|||
|
|||
|
|||
def reverse_populate(apps, schema_editor): |
|||
pass |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('hadis', '0049_alter_bookreference_normalized_text_and_more'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AddField( |
|||
model_name='hadis', |
|||
name='categories', |
|||
field=models.ManyToManyField(blank=True, related_name='hadis_items', to='hadis.hadiscategory', verbose_name='categories'), |
|||
), |
|||
migrations.RunPython(populate_categories_from_category, reverse_populate), |
|||
] |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue