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 query