Browse Source
feat(hadis): enhance hadis management with collections and new endpoints
feat(hadis): enhance hadis management with collections and new endpoints
- Introduced `HadisCollection` and `HadisInCollection` models to manage collections of hadis. - Updated URL patterns to include new endpoints for collections and syncing hadis data. - Enhanced admin interface to support management of hadis collections and their items. - Added serializers for handling collections and syncing hadis data. - Implemented a new API view for retrieving hadis statistics. - Refactored existing serializers and views to accommodate new features and improve data handling.master
16 changed files with 866 additions and 88 deletions
-
44apps/hadis/admin/hadis.py
-
11apps/hadis/admin/transmitter.py
-
226apps/hadis/migrations/0003_bookreference_narratorlayer_and_more.py
-
52apps/hadis/migrations/0004_hadiscollection_hadisincollection.py
-
3apps/hadis/models/__init__.py
-
4apps/hadis/models/category.py
-
71apps/hadis/models/hadis.py
-
109apps/hadis/models/reference.py
-
156apps/hadis/models/transmitter.py
-
42apps/hadis/serializers/category.py
-
59apps/hadis/serializers/hadis.py
-
21apps/hadis/urls.py
-
2apps/hadis/views/__init__.py
-
77apps/hadis/views/category.py
-
47apps/hadis/views/hadis.py
-
30apps/hadis/views/info.py
@ -0,0 +1,226 @@ |
|||||
|
# Generated by Django 5.1.8 on 2025-12-03 23:32 |
||||
|
|
||||
|
import django.db.models.deletion |
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('hadis', '0002_hadissect_hadisstatus_alter_hadis_options_and_more'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.CreateModel( |
||||
|
name='BookReference', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('title', models.CharField(max_length=500, verbose_name='title')), |
||||
|
('description', models.TextField(blank=True, null=True, verbose_name='description')), |
||||
|
('language', models.CharField(blank=True, max_length=100, null=True, verbose_name='language')), |
||||
|
('isbn', models.CharField(blank=True, max_length=100, null=True, verbose_name='ISBN')), |
||||
|
('volume', models.CharField(blank=True, max_length=100, null=True, verbose_name='volume')), |
||||
|
('year_of_publication', models.CharField(blank=True, max_length=50, null=True, verbose_name='year of publication')), |
||||
|
('number_page', models.PositiveIntegerField(blank=True, null=True, verbose_name='number of pages')), |
||||
|
('rate', models.DecimalField(blank=True, decimal_places=2, help_text='Rating from 0 to 5', max_digits=3, null=True, verbose_name='rate')), |
||||
|
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')), |
||||
|
('updated_at', models.DateTimeField(auto_now=True, verbose_name='updated at')), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'Book Reference', |
||||
|
'verbose_name_plural': 'Book References', |
||||
|
'ordering': ('-created_at',), |
||||
|
}, |
||||
|
), |
||||
|
migrations.CreateModel( |
||||
|
name='NarratorLayer', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('name', models.CharField(max_length=255, verbose_name='name')), |
||||
|
('number', models.PositiveIntegerField(unique=True, verbose_name='layer number')), |
||||
|
('description', models.TextField(blank=True, null=True, verbose_name='description')), |
||||
|
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')), |
||||
|
('updated_at', models.DateTimeField(auto_now=True, verbose_name='updated at')), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'Narrator Layer', |
||||
|
'verbose_name_plural': 'Narrator Layers', |
||||
|
'ordering': ['number'], |
||||
|
}, |
||||
|
), |
||||
|
migrations.AlterUniqueTogether( |
||||
|
name='hadisreference', |
||||
|
unique_together=set(), |
||||
|
), |
||||
|
migrations.RemoveField( |
||||
|
model_name='hadistransmitter', |
||||
|
name='is_gap', |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='hadis', |
||||
|
name='title_narrator', |
||||
|
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='title narrator'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='hadiscategory', |
||||
|
name='description', |
||||
|
field=models.TextField(blank=True, null=True, verbose_name='Description'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='hadissect', |
||||
|
name='description', |
||||
|
field=models.TextField(blank=True, null=True, verbose_name='Description'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='transmitters', |
||||
|
name='age_at_death', |
||||
|
field=models.PositiveIntegerField(blank=True, null=True, verbose_name='Age at Death'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='transmitters', |
||||
|
name='died_in', |
||||
|
field=models.CharField(blank=True, help_text='Place of death', max_length=255, null=True, verbose_name='Died In'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='transmitters', |
||||
|
name='in_sahih_bukhari', |
||||
|
field=models.BooleanField(default=False, help_text='Is this narrator present in Sahih Bukhari?', verbose_name='In Sahih Bukhari'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='transmitters', |
||||
|
name='in_sahih_muslim', |
||||
|
field=models.BooleanField(default=False, help_text='Is this narrator present in Sahih Muslim?', verbose_name='In Sahih Muslim'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='transmitters', |
||||
|
name='known_as', |
||||
|
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Known As'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='transmitters', |
||||
|
name='kunya', |
||||
|
field=models.CharField(blank=True, help_text='e.g., Abu Abdullah', max_length=255, null=True, verbose_name='Kunya'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='transmitters', |
||||
|
name='lived_in', |
||||
|
field=models.CharField(blank=True, help_text='Places where they lived', max_length=255, null=True, verbose_name='Lived In'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='transmitters', |
||||
|
name='madhhab', |
||||
|
field=models.CharField(choices=[('shia', 'Shia'), ('sunni', 'Sunni'), ('hanafi', 'Hanafi'), ('maliki', 'Maliki'), ('shafii', "Shafi'i"), ('hanbali', 'Hanbali'), ('other', 'Other'), ('unknown', 'Unknown')], default='unknown', max_length=20, verbose_name='Madhhab/School of Thought'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='transmitters', |
||||
|
name='nickname', |
||||
|
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Nickname/Laqab'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='transmitters', |
||||
|
name='origin', |
||||
|
field=models.CharField(blank=True, help_text='Place of origin', max_length=255, null=True, verbose_name='Origin'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='transmitters', |
||||
|
name='reliability', |
||||
|
field=models.CharField(choices=[('very_reliable', 'Very Reliable'), ('reliable', 'Reliable'), ('acceptable', 'Acceptable'), ('weak', 'Weak'), ('very_weak', 'Very Weak'), ('unknown', 'Unknown')], default='unknown', max_length=20, verbose_name='Reliability Level'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='hadiscategory', |
||||
|
name='source_type', |
||||
|
field=models.CharField(choices=[('quran', 'Quran'), ('hadith', 'Hadith'), ('history', 'History'), ('fatwa', 'Fatwa'), ('quote', 'Quote')], max_length=10, verbose_name='Source Type'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='hadistransmitter', |
||||
|
name='status', |
||||
|
field=models.CharField(choices=[('reliable', 'Reliable'), ('weak', 'Weak'), ('unknown', 'Unknown')], default='unknown', help_text='Reliability status of the narrator', max_length=20, verbose_name='reliability status'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='hadistransmitter', |
||||
|
name='transmitter', |
||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='hadises', to='hadis.transmitters', verbose_name='transmitter'), |
||||
|
), |
||||
|
migrations.CreateModel( |
||||
|
name='BookAuthor', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('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')), |
||||
|
('book_references', models.ManyToManyField(blank=True, related_name='authors', to='hadis.bookreference', verbose_name='book references')), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'Book Author', |
||||
|
'verbose_name_plural': 'Book Authors', |
||||
|
'ordering': ['name'], |
||||
|
}, |
||||
|
), |
||||
|
migrations.CreateModel( |
||||
|
name='BookAttribute', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('title', models.CharField(max_length=255, verbose_name='title')), |
||||
|
('value', models.CharField(max_length=500, verbose_name='value')), |
||||
|
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')), |
||||
|
('updated_at', models.DateTimeField(auto_now=True, verbose_name='updated at')), |
||||
|
('book_references', models.ManyToManyField(blank=True, related_name='attributes', to='hadis.bookreference', verbose_name='book references')), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'Book Attribute', |
||||
|
'verbose_name_plural': 'Book Attributes', |
||||
|
'ordering': ['title'], |
||||
|
}, |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='hadisreference', |
||||
|
name='book_reference', |
||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='hadis_references', to='hadis.bookreference', verbose_name='book reference'), |
||||
|
), |
||||
|
migrations.CreateModel( |
||||
|
name='BookReferenceImage', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('image', models.ImageField(upload_to='hadis/book_reference_images/', verbose_name='image')), |
||||
|
('order', models.PositiveIntegerField(default=0, verbose_name='order')), |
||||
|
('description', models.CharField(blank=True, max_length=255, null=True, verbose_name='description')), |
||||
|
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')), |
||||
|
('book_reference', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='hadis.bookreference', verbose_name='book reference')), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'Book Reference Image', |
||||
|
'verbose_name_plural': 'Book Reference Images', |
||||
|
'ordering': ['order', '-created_at'], |
||||
|
}, |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='hadistransmitter', |
||||
|
name='narrator_layer', |
||||
|
field=models.ForeignKey(blank=True, help_text='The layer/class (Tabaqah) this narrator belongs to', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='transmitters', to='hadis.narratorlayer', verbose_name='narrator layer'), |
||||
|
), |
||||
|
migrations.CreateModel( |
||||
|
name='TransmitterOpinion', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('scholar_name', models.CharField(help_text='Name of the scholar who gave this opinion', max_length=255, verbose_name='Scholar Name')), |
||||
|
('opinion_text', models.TextField(help_text="The scholar's opinion about this transmitter", verbose_name='Opinion Text')), |
||||
|
('status', models.CharField(choices=[('confirmed', 'Confirmed'), ('mixed', 'Mixed'), ('rejected', 'Rejected')], default='confirmed', help_text='Status of the opinion', max_length=20, verbose_name='Opinion Status')), |
||||
|
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')), |
||||
|
('updated_at', models.DateTimeField(auto_now=True, verbose_name='updated at')), |
||||
|
('transmitter', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='opinions', to='hadis.transmitters', verbose_name='transmitter')), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'Transmitter Opinion', |
||||
|
'verbose_name_plural': 'Transmitter Opinions', |
||||
|
'ordering': ('-created_at',), |
||||
|
}, |
||||
|
), |
||||
|
migrations.RemoveField( |
||||
|
model_name='hadisreference', |
||||
|
name='book', |
||||
|
), |
||||
|
migrations.RemoveField( |
||||
|
model_name='hadisreference', |
||||
|
name='description', |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,52 @@ |
|||||
|
# Generated by Django 3.2.4 on 2025-12-05 17:07 |
||||
|
|
||||
|
from django.conf import settings |
||||
|
from django.db import migrations, models |
||||
|
import django.db.models.deletion |
||||
|
import filer.fields.image |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
migrations.swappable_dependency(settings.FILER_IMAGE_MODEL), |
||||
|
('hadis', '0003_bookreference_narratorlayer_and_more'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.CreateModel( |
||||
|
name='HadisCollection', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('title', models.CharField(max_length=255, verbose_name='title')), |
||||
|
('slug', models.SlugField(blank=True, max_length=255, unique=True, verbose_name='slug')), |
||||
|
('summary', models.TextField(blank=True, null=True, verbose_name='summary')), |
||||
|
('status', models.BooleanField(default=True, verbose_name='status')), |
||||
|
('order', models.IntegerField(default=0, verbose_name='order')), |
||||
|
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')), |
||||
|
('updated_at', models.DateTimeField(auto_now=True, verbose_name='updated at')), |
||||
|
('thumbnail', filer.fields.image.FilerImageField(blank=True, help_text='thumbnail image', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.FILER_IMAGE_MODEL, verbose_name='thumbnail')), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'hadis collection', |
||||
|
'verbose_name_plural': 'hadis collections', |
||||
|
'ordering': ('order',), |
||||
|
}, |
||||
|
), |
||||
|
migrations.CreateModel( |
||||
|
name='HadisInCollection', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('order', models.IntegerField(default=0, verbose_name='order')), |
||||
|
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')), |
||||
|
('collection', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='hadis_items', to='hadis.hadiscollection', verbose_name='collection')), |
||||
|
('hadis', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='collection_items', to='hadis.hadis', verbose_name='hadis')), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'hadis in collection', |
||||
|
'verbose_name_plural': 'hadis in collections', |
||||
|
'ordering': ('order',), |
||||
|
'unique_together': {('hadis', 'collection')}, |
||||
|
}, |
||||
|
), |
||||
|
] |
||||
@ -1,3 +1,4 @@ |
|||||
from .category import * |
from .category import * |
||||
from .hadis import * |
from .hadis import * |
||||
from .transmitter import * |
|
||||
|
from .transmitter import * |
||||
|
from .reference import * |
||||
@ -0,0 +1,109 @@ |
|||||
|
from django.db import models |
||||
|
from django.utils.translation import gettext_lazy as _ |
||||
|
|
||||
|
|
||||
|
class BookReference(models.Model): |
||||
|
""" |
||||
|
Model for hadis book references with detailed information |
||||
|
This is different from library books - these are reference books for hadis |
||||
|
""" |
||||
|
title = models.CharField(max_length=500, verbose_name=_('title')) |
||||
|
description = models.TextField(verbose_name=_('description'), blank=True, null=True) |
||||
|
language = models.CharField(max_length=100, verbose_name=_('language'), blank=True, null=True) |
||||
|
isbn = models.CharField(max_length=100, verbose_name=_('ISBN'), blank=True, null=True) |
||||
|
volume = models.CharField(max_length=100, verbose_name=_('volume'), blank=True, null=True) |
||||
|
year_of_publication = models.CharField(max_length=50, verbose_name=_('year of publication'), blank=True, null=True) |
||||
|
number_page = models.PositiveIntegerField(verbose_name=_('number of pages'), blank=True, null=True) |
||||
|
rate = models.DecimalField( |
||||
|
max_digits=3, |
||||
|
decimal_places=2, |
||||
|
verbose_name=_('rate'), |
||||
|
blank=True, |
||||
|
null=True, |
||||
|
help_text=_('Rating from 0 to 5') |
||||
|
) |
||||
|
|
||||
|
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 = _('Book Reference') |
||||
|
verbose_name_plural = _('Book References') |
||||
|
ordering = ('-created_at',) |
||||
|
|
||||
|
def __str__(self): |
||||
|
return self.title |
||||
|
|
||||
|
|
||||
|
class BookReferenceImage(models.Model): |
||||
|
""" |
||||
|
Model for book reference images - multiple images per book reference |
||||
|
""" |
||||
|
book_reference = models.ForeignKey( |
||||
|
BookReference, |
||||
|
on_delete=models.CASCADE, |
||||
|
related_name='images', |
||||
|
verbose_name=_('book reference') |
||||
|
) |
||||
|
image = models.ImageField(upload_to='hadis/book_reference_images/', verbose_name=_('image')) |
||||
|
order = models.PositiveIntegerField(default=0, verbose_name=_('order')) |
||||
|
description = models.CharField(max_length=255, verbose_name=_('description'), blank=True, null=True) |
||||
|
|
||||
|
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_('created at')) |
||||
|
|
||||
|
class Meta: |
||||
|
verbose_name = _('Book Reference Image') |
||||
|
verbose_name_plural = _('Book Reference Images') |
||||
|
ordering = ['order', '-created_at'] |
||||
|
|
||||
|
def __str__(self): |
||||
|
return f"{self.book_reference.title} - Image {self.order}" |
||||
|
|
||||
|
|
||||
|
class BookAuthor(models.Model): |
||||
|
""" |
||||
|
Model for book reference authors |
||||
|
""" |
||||
|
name = models.CharField(max_length=255, verbose_name=_('name')) |
||||
|
book_references = models.ManyToManyField( |
||||
|
BookReference, |
||||
|
related_name='authors', |
||||
|
verbose_name=_('book references'), |
||||
|
blank=True |
||||
|
) |
||||
|
|
||||
|
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 = _('Book Author') |
||||
|
verbose_name_plural = _('Book Authors') |
||||
|
ordering = ['name'] |
||||
|
|
||||
|
def __str__(self): |
||||
|
return self.name |
||||
|
|
||||
|
|
||||
|
class BookAttribute(models.Model): |
||||
|
""" |
||||
|
Model for book reference attributes - custom key-value pairs |
||||
|
""" |
||||
|
title = models.CharField(max_length=255, verbose_name=_('title')) |
||||
|
value = models.CharField(max_length=500, verbose_name=_('value')) |
||||
|
book_references = models.ManyToManyField( |
||||
|
BookReference, |
||||
|
related_name='attributes', |
||||
|
verbose_name=_('book references'), |
||||
|
blank=True |
||||
|
) |
||||
|
|
||||
|
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 = _('Book Attribute') |
||||
|
verbose_name_plural = _('Book Attributes') |
||||
|
ordering = ['title'] |
||||
|
|
||||
|
def __str__(self): |
||||
|
return f"{self.title}: {self.value}" |
||||
@ -1,16 +1,15 @@ |
|||||
from django.urls import path |
from django.urls import path |
||||
from .views.category import HadisSectListView, HadisCategoryTreeView |
|
||||
from .views.hadis import HadisListView, HadisDetailView |
|
||||
|
from .views.category import HadisCategorySectListView, HadisCategoryTreeView |
||||
|
from .views.hadis import HadisCollectionListView, HadisListView, HadisDetailView, HadisSyncView |
||||
|
from .views.info import HadisInfoView |
||||
|
|
||||
|
|
||||
urlpatterns = [ |
urlpatterns = [ |
||||
# Hadis Sect endpoints |
|
||||
path('categories/', HadisSectListView.as_view(), name='hadis-sect-list'), |
|
||||
|
|
||||
# Hadis Category endpoints |
|
||||
path('categories/<int:sect_id>/', HadisCategoryTreeView.as_view(), name='hadis-category-tree'), |
|
||||
|
|
||||
# Hadis endpoints |
|
||||
path('<int:category_id>/hadis/', HadisListView.as_view(), name='hadis-list'), |
|
||||
path('hadis/<int:hadis_id>/', HadisDetailView.as_view(), name='hadis-detail'), |
|
||||
|
path('collections/', HadisCollectionListView.as_view(), name='hadis-collection-list'), |
||||
|
path('sync/sects/', HadisCategorySectListView.as_view(), name='hadis-sect-list'), |
||||
|
path('sync/categories/tree/', HadisCategoryTreeView.as_view(), name='hadis-category-tree'), |
||||
|
path('sync/hadis/', HadisSyncView.as_view(), name='hadis-sync'), |
||||
|
path('info/', HadisInfoView.as_view(), name='hadis-info'), |
||||
|
path('category/<int:category_id>/', HadisListView.as_view(), name='hadis-list'), |
||||
|
path('<int:hadis_id>/', HadisDetailView.as_view(), name='hadis-detail'), |
||||
] |
] |
||||
@ -1,3 +1,3 @@ |
|||||
from .category import * |
from .category import * |
||||
from .hadis import * |
from .hadis import * |
||||
# from .transmitter import * |
|
||||
|
from .info import * |
||||
@ -0,0 +1,30 @@ |
|||||
|
from rest_framework.views import APIView |
||||
|
from rest_framework.response import Response |
||||
|
from rest_framework import status |
||||
|
|
||||
|
from ..models import HadisSect, BookReference, Transmitters |
||||
|
from apps.bookmark.models import Bookmark |
||||
|
|
||||
|
|
||||
|
class HadisInfoView(APIView): |
||||
|
""" |
||||
|
API view to get hadis statistics |
||||
|
""" |
||||
|
|
||||
|
def get(self, request, *args, **kwargs): |
||||
|
category_count = HadisSect.objects.filter(is_active=True).count() |
||||
|
reference_count = BookReference.objects.count() |
||||
|
bookmark_count = Bookmark.objects.filter( |
||||
|
service=Bookmark.ServiceChoices.HADITH, |
||||
|
status=True |
||||
|
).count() |
||||
|
narrator_count = Transmitters.objects.count() |
||||
|
|
||||
|
data = { |
||||
|
'category_count': category_count, |
||||
|
'reference_count': reference_count, |
||||
|
'bookmark_count': bookmark_count, |
||||
|
'narrator_count': narrator_count |
||||
|
} |
||||
|
|
||||
|
return Response(data, status=status.HTTP_200_OK) |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue