Browse Source

collections updated

master
Mohsen Taba 1 day ago
parent
commit
85b87efd93
  1. 4
      apps/article/admin.py
  2. 3
      apps/article/management/commands/seed_article_data.py
  3. 17
      apps/article/migrations/0003_remove_articlecollection_pin_top.py
  4. 1
      apps/article/models.py
  5. 2
      apps/article/serializers.py
  6. 2
      apps/article/serializers_admin.py
  7. 1
      apps/article/serializers_dovodi.py
  8. 4
      apps/article/views.py
  9. 6
      apps/hadis/admin/hadis.py
  10. 22
      apps/hadis/migrations/0031_remove_hadiscollection_pin_top_and_more.py
  11. 11
      apps/hadis/models/hadis.py
  12. 2
      apps/hadis/serializers/serializers_admin.py
  13. 9
      apps/hadis/views/hadis.py
  14. 2
      apps/library/admin.py
  15. 2
      apps/library/management/commands/seed_category_collection.py
  16. 27
      apps/library/migrations/0007_remove_bookcollection_pin_top_and_more.py
  17. 3
      apps/library/models.py
  18. 3
      apps/library/serializers_admin.py
  19. 4
      apps/library/views.py
  20. 4
      apps/podcast/admin.py
  21. 17
      apps/podcast/migrations/0003_remove_podcastcollection_pin_top.py
  22. 1
      apps/podcast/models.py
  23. 2
      apps/podcast/serializers.py
  24. 2
      apps/podcast/serializers_admin.py
  25. 1
      apps/podcast/serializers_dovodi.py
  26. 4
      apps/podcast/views.py
  27. 4
      apps/video/admin.py
  28. 17
      apps/video/migrations/0003_remove_videocollection_pin_top.py
  29. 1
      apps/video/models.py
  30. 2
      apps/video/serializers.py
  31. 2
      apps/video/serializers_admin.py
  32. 1
      apps/video/serializers_dovodi.py
  33. 4
      apps/video/views.py

4
apps/article/admin.py

@ -81,7 +81,7 @@ class ArticleCollectionAdminBase(ModelAdmin):
fieldsets = (
(None, {
'fields': ('title', 'summary', 'thumbnail', 'status', 'pin_top', 'order')
'fields': ('title', 'summary', 'thumbnail', 'status', 'order')
}),
)
@ -152,7 +152,7 @@ class MiddleArticleCollectionAdmin(ArticleCollectionAdminBase):
fieldsets = (
(None, {
'fields': ('title', 'status', 'pin_top', 'order')
'fields': ('title', 'status', 'order')
}),
)

3
apps/article/management/commands/seed_article_data.py

@ -59,14 +59,12 @@ class Command(BaseCommand):
{
'title': 'Избранные статьи об имамах',
'summary': 'Лучшие статьи о жизни и учениях имамов',
'pin_top': True,
'display_position': 'pinned',
'order': 1
},
{
'title': 'Коллекция о пророках',
'summary': 'Статьи о пророках в исламе',
'pin_top': False,
'display_position': 'middle',
'order': 2
},
@ -79,7 +77,6 @@ class Command(BaseCommand):
defaults={
'slug': slugify(coll_data['title'], allow_unicode=True),
'summary': coll_data['summary'],
'pin_top': coll_data['pin_top'],
'display_position': coll_data['display_position'],
'order': coll_data['order'],
'status': True

17
apps/article/migrations/0003_remove_articlecollection_pin_top.py

@ -0,0 +1,17 @@
# Generated by Django 4.2.30 on 2026-07-20 15:49
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('article', '0002_article_embedded_in'),
]
operations = [
migrations.RemoveField(
model_name='articlecollection',
name='pin_top',
),
]

1
apps/article/models.py

@ -32,7 +32,6 @@ class ArticleCollection(LowercaseSlugMixin, models.Model):
title = models.CharField(max_length=255, help_text="This title will not be displayed anywhere")
slug = models.SlugField(max_length=255, unique=True)
summary = models.CharField(max_length=512, null=True, blank=True, help_text=_('could be null'))
pin_top = models.BooleanField(_('pin top'), default=True)
thumbnail = models.ImageField(upload_to='article/collection/', null=True, blank=True, help_text=_('image allowed'))
order = models.IntegerField(default=0, verbose_name=_('order'))
status = models.BooleanField(default=True, verbose_name=_('status'))

2
apps/article/serializers.py

@ -32,7 +32,7 @@ class MiddleArticleCollectionSerializer(serializers.ModelSerializer):
class Meta:
model = ArticleCollection
fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'pin_top', 'articles')
fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'articles')
def get_articles(self, obj):
articles = obj.articles.filter(status=True).order_by('-created_at')

2
apps/article/serializers_admin.py

@ -48,7 +48,7 @@ class AdminArticleCategorySerializer(serializers.ModelSerializer):
class AdminArticleCollectionSerializer(serializers.ModelSerializer):
class Meta:
model = ArticleCollection
fields = ["id", "title", "slug", "summary", "display_position", "status", "order", "pin_top"]
fields = ["id", "title", "slug", "summary", "display_position", "status", "order"]
class AdminArticleListSerializer(serializers.ModelSerializer):

1
apps/article/serializers_dovodi.py

@ -27,7 +27,6 @@ class DovodiArticleCollectionSerializer(serializers.ModelSerializer):
"display_position",
"status",
"order",
"pin_top",
"thumbnail",
"remove_thumbnail",
]

4
apps/article/views.py

@ -65,7 +65,7 @@ class PinnedArticleCollectionListView(generics.ListAPIView):
return PinnedArticleCollection.objects.filter(
status=True,
display_position=ArticleCollection.DisplayPosition.PINNED
).order_by('-order', '-id')
).order_by('order', '-created_at')
def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
@ -112,7 +112,7 @@ class MiddleArticleCollectionListView(generics.ListAPIView):
return ArticleCollection.objects.filter(
status=True,
display_position=ArticleCollection.DisplayPosition.MIDDLE
).order_by('order')
).order_by('order', '-created_at')

6
apps/hadis/admin/hadis.py

@ -748,8 +748,8 @@ class HadisInCollectionInline(TabularInline):
class HadisCollectionAdmin(ModelAdmin):
"""Admin for HadisCollection model"""
form = HadisCollectionAdminForm
list_display = ('display_header','get_title_display', 'slug', 'status', 'order', 'created_at')
list_filter = ('status', 'created_at')
list_display = ('display_header','get_title_display', 'slug', 'display_position', 'status', 'order', 'created_at')
list_filter = ('status', 'display_position', 'created_at')
search_fields = ('title', 'slug', 'summary')
readonly_fields = ('slug', 'created_at', 'updated_at')
ordering = ('order',)
@ -757,7 +757,7 @@ class HadisCollectionAdmin(ModelAdmin):
fieldsets = (
(None, {
'fields': ('title', 'slug', 'summary', 'status','pin_top', 'order','thumbnail')
'fields': ('title', 'slug', 'summary', 'status', 'display_position', 'order', 'thumbnail')
}),
(_('Timestamps'), {
'fields': ('created_at', 'updated_at'),

22
apps/hadis/migrations/0031_remove_hadiscollection_pin_top_and_more.py

@ -0,0 +1,22 @@
# Generated by Django 4.2.30 on 2026-07-20 15:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('hadis', '0030_remove_bookauthor_book_references_and_more'),
]
operations = [
migrations.RemoveField(
model_name='hadiscollection',
name='pin_top',
),
migrations.AddField(
model_name='hadiscollection',
name='display_position',
field=models.CharField(choices=[('pinned', 'Pinned'), ('middle', 'Middle Section')], default='pinned', max_length=20, verbose_name='Display Position'),
),
]

11
apps/hadis/models/hadis.py

@ -10,12 +10,21 @@ from utils.slug import generate_smart_slug
from utils.mixins import ColorPaletteMixin, LowercaseSlugMixin
class HadisCollection(LowercaseSlugMixin, models.Model):
class DisplayPosition(models.TextChoices):
PINNED = 'pinned', _('Pinned')
MIDDLE = 'middle', _('Middle Section')
slug_source_field = 'title'
title = models.JSONField(default = list , verbose_name=_('Title'))
slug = models.SlugField(max_length=255, unique=True, verbose_name=_('slug'), blank=True)
summary = models.JSONField(default = list , verbose_name=_('Summary'))
status = models.BooleanField(default=True, verbose_name=_('status'))
pin_top = models.BooleanField(default=False, verbose_name=_('pin top'))
display_position = models.CharField(
max_length=20,
choices=DisplayPosition.choices,
default=DisplayPosition.PINNED,
verbose_name=_('Display Position')
)
order = models.IntegerField(default=0, verbose_name=_('order'))
thumbnail = models.ImageField(upload_to='hadis/collection_thumbnails/', null=True, blank=True, help_text=_('image allowed'))
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_('created at'))

2
apps/hadis/serializers/serializers_admin.py

@ -118,7 +118,7 @@ class AdminHadisCollectionSerializer(serializers.ModelSerializer):
"slug",
"summary",
"status",
"pin_top",
"display_position",
"order",
"thumbnail",
"remove_thumbnail",

9
apps/hadis/views/hadis.py

@ -33,7 +33,7 @@ class PinnedHadisCollectionListView(ListAPIView):
def get_queryset(self):
return HadisCollection.objects.filter(
status=True,
pin_top=True
display_position=HadisCollection.DisplayPosition.PINNED
).order_by('order', '-created_at')
def list(self, request, *args, **kwargs):
@ -89,7 +89,6 @@ class HadisCollectionListView(ListAPIView):
"""
API view to list all hadis collections
"""
queryset = HadisCollection.objects.filter(status=True).order_by('order')
serializer_class = HadisCollectionListSerializer
pagination_class = NoPagination
@ -97,6 +96,12 @@ class HadisCollectionListView(ListAPIView):
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def get_queryset(self):
return HadisCollection.objects.filter(
status=True,
display_position=HadisCollection.DisplayPosition.MIDDLE
).order_by('order', '-created_at')
class HadisSyncView(ListAPIView):
"""

2
apps/library/admin.py

@ -142,7 +142,7 @@ class PinnedBookCollectionAdmin(BookCollectionAdminBase):
fieldsets = (
(None, {
'fields': ('title', 'summary', 'status', 'order', 'pin_top')
'fields': ('title', 'summary', 'status', 'order')
}),
(_('Books'), {
'fields': ('books',)

2
apps/library/management/commands/seed_category_collection.py

@ -38,7 +38,7 @@ class Command(BaseCommand):
for item in collections_data:
col, created = BookCollection.objects.get_or_create(
title=item['title'],
defaults={'display_position': item['pos'], 'pin_top': True}
defaults={'display_position': item['pos']}
)
collection_objs.append(col)
if created:

27
apps/library/migrations/0007_remove_bookcollection_pin_top_and_more.py

@ -0,0 +1,27 @@
# Generated by Django 4.2.30 on 2026-07-20 15:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('library', '0006_alter_author_number_of_volumes'),
]
operations = [
migrations.RemoveField(
model_name='bookcollection',
name='pin_top',
),
migrations.AddField(
model_name='bookcollection',
name='created_at',
field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='created at'),
),
migrations.AddField(
model_name='bookcollection',
name='updated_at',
field=models.DateTimeField(auto_now=True, null=True, verbose_name='updated at'),
),
]

3
apps/library/models.py

@ -20,7 +20,6 @@ class BookCollection(LowercaseSlugMixin, models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255, unique=True, blank=True, null=True)
summary = models.CharField(max_length=512, null=True, blank=True, help_text=_('could be null'))
pin_top = models.BooleanField(_('pin top'), default=True)
display_position = models.CharField(
max_length=20,
choices=DisplayPosition.choices,
@ -29,6 +28,8 @@ class BookCollection(LowercaseSlugMixin, models.Model):
)
status = models.BooleanField(_('status'), default=True)
order = models.IntegerField(default=0, verbose_name=_('order'))
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_('created at'), null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, verbose_name=_('updated at'), null=True, blank=True)
books = models.ManyToManyField('library.Book', related_name='related_collections_books',through="library.Book_collections" ,verbose_name=_('Books'), blank=True)
def __str__(self):

3
apps/library/serializers_admin.py

@ -58,7 +58,8 @@ class AdminLibraryCollectionSerializer(serializers.ModelSerializer):
class Meta:
model = BookCollection
fields = ["id", "title", "slug", "summary", "display_position", "status", "order", "pin_top"]
fields = ["id", "title", "slug", "summary", "display_position", "status", "order", "created_at", "updated_at"]
read_only_fields = ["id", "created_at", "updated_at"]
class AdminAuthorSerializer(serializers.ModelSerializer):

4
apps/library/views.py

@ -68,7 +68,7 @@ class PinnedBookCollectionListView(ListAPIView):
return BookCollection.objects.filter(
status=True,
display_position=BookCollection.DisplayPosition.PINNED
).order_by('-order', '-id')
).order_by('order', '-created_at')
def list(self, request, *args, **kwargs):
@ -249,7 +249,7 @@ class MiddleBookCollectionListView(ListAPIView):
return BookCollection.objects.filter(
status=True,
display_position=BookCollection.DisplayPosition.MIDDLE
).order_by('order')
).order_by('order', '-created_at')
class AuthorListView(ListAPIView):

4
apps/podcast/admin.py

@ -40,7 +40,7 @@ class PodcastCollectionAdminBase(ModelAdmin):
fieldsets = (
(None, {
'fields': ('title', 'summary', 'thumbnail', 'status', 'pin_top', 'order')
'fields': ('title', 'summary', 'thumbnail', 'status', 'order')
}),
)
@ -101,7 +101,7 @@ class MiddlePodcastCollectionAdmin(PodcastCollectionAdminBase):
fieldsets = (
(None, {
'fields': ('title', 'status', 'pin_top', 'order')
'fields': ('title', 'status', 'order')
}),
)

17
apps/podcast/migrations/0003_remove_podcastcollection_pin_top.py

@ -0,0 +1,17 @@
# Generated by Django 4.2.30 on 2026-07-20 15:49
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('podcast', '0002_podcast_collections'),
]
operations = [
migrations.RemoveField(
model_name='podcastcollection',
name='pin_top',
),
]

1
apps/podcast/models.py

@ -33,7 +33,6 @@ class PodcastCollection(LowercaseSlugMixin, models.Model):
title = models.CharField(max_length=255, help_text="This title will not be displayed anywhere")
slug = models.SlugField(max_length=255, unique=True)
summary = models.CharField(max_length=512, null=True, blank=True, help_text=_('could be null'))
pin_top = models.BooleanField(_('pin top'), default=True)
thumbnail = models.ImageField(upload_to='podcast/collection/', null=True, blank=True, help_text=_('image allowed'))
order = models.IntegerField(default=0, verbose_name=_('order'))
status = models.BooleanField(default=True, verbose_name=_('status'))

2
apps/podcast/serializers.py

@ -295,7 +295,7 @@ class MiddlePodcastCollectionSerializer(serializers.ModelSerializer):
class Meta:
model = PodcastCollection
fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'pin_top', 'playlists')
fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'playlists')
def get_playlists(self, obj):
playlists = obj.related_playlists.filter(status=True).order_by('order', '-created_at')

2
apps/podcast/serializers_admin.py

@ -48,7 +48,7 @@ class AdminPodcastCategorySerializer(serializers.ModelSerializer):
class AdminPodcastCollectionSerializer(serializers.ModelSerializer):
class Meta:
model = PodcastCollection
fields = ["id", "title", "slug", "summary", "display_position", "status", "order", "pin_top"]
fields = ["id", "title", "slug", "summary", "display_position", "status", "order"]
class AdminPodcastListSerializer(serializers.ModelSerializer):

1
apps/podcast/serializers_dovodi.py

@ -27,7 +27,6 @@ class DovodiPodcastCollectionSerializer(serializers.ModelSerializer):
"display_position",
"status",
"order",
"pin_top",
"thumbnail",
"remove_thumbnail",
]

4
apps/podcast/views.py

@ -71,7 +71,7 @@ class PinnedPodcastCollectionListView(generics.ListAPIView):
return PinnedPodcastCollection.objects.filter(
status=True,
display_position=PodcastCollection.DisplayPosition.PINNED
).order_by('-order', '-id')
).order_by('order', '-created_at')
def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
@ -121,7 +121,7 @@ class MiddlePodcastCollectionListView(generics.ListAPIView):
return PodcastCollection.objects.filter(
status=True,
display_position=PodcastCollection.DisplayPosition.MIDDLE
).order_by('order')
).order_by('order', '-created_at')
class PodcastListAPIView(generics.ListAPIView):

4
apps/video/admin.py

@ -40,7 +40,7 @@ class VideoCollectionAdminBase(ModelAdmin):
fieldsets = (
(None, {
'fields': ('title', 'summary', 'thumbnail' , 'status', 'pin_top', 'order')
'fields': ('title', 'summary', 'thumbnail' , 'status', 'order')
}),
)
@ -103,7 +103,7 @@ class MiddleVideoCollectionAdmin(VideoCollectionAdminBase):
fieldsets = (
(None, {
'fields': ('title', 'status', 'pin_top', 'order')
'fields': ('title', 'status', 'order')
}),
)

17
apps/video/migrations/0003_remove_videocollection_pin_top.py

@ -0,0 +1,17 @@
# Generated by Django 4.2.30 on 2026-07-20 15:49
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('video', '0002_alter_video_video_file'),
]
operations = [
migrations.RemoveField(
model_name='videocollection',
name='pin_top',
),
]

1
apps/video/models.py

@ -35,7 +35,6 @@ class VideoCollection(LowercaseSlugMixin, models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255, unique=True)
summary = models.CharField(max_length=512, null=True, blank=True, help_text=_('could be null'))
pin_top = models.BooleanField(_('pin top'), default=True)
thumbnail = models.ImageField(upload_to='video/collection/', null=True, blank=True, help_text=_('image allowed'))
order = models.IntegerField(default=0, verbose_name=_('order'))

2
apps/video/serializers.py

@ -283,7 +283,7 @@ class MiddleVideoCollectionSerializer(serializers.ModelSerializer):
class Meta:
model = VideoCollection
fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'pin_top','playlists')
fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'playlists')
def get_playlists(self, obj):
playlists = obj.related_playlists.filter(status=True).order_by('order', '-created_at')

2
apps/video/serializers_admin.py

@ -48,7 +48,7 @@ class AdminVideoCategorySerializer(serializers.ModelSerializer):
class AdminVideoCollectionSerializer(serializers.ModelSerializer):
class Meta:
model = VideoCollection
fields = ["id", "title", "slug", "summary", "display_position", "status", "order", "pin_top"]
fields = ["id", "title", "slug", "summary", "display_position", "status", "order"]
class AdminVideoListSerializer(serializers.ModelSerializer):

1
apps/video/serializers_dovodi.py

@ -27,7 +27,6 @@ class DovodiVideoCollectionSerializer(serializers.ModelSerializer):
"display_position",
"status",
"order",
"pin_top",
"thumbnail",
"remove_thumbnail",
]

4
apps/video/views.py

@ -84,7 +84,7 @@ class PinnedVideoCollectionListView(generics.ListAPIView):
queryset = PinnedVideoCollection.objects.filter(
status=True,
display_position=VideoCollection.DisplayPosition.PINNED
).order_by('-order', '-id')
).order_by('order', '-created_at')
# Filter by bookmarks if requested
is_bookmark = self.request.query_params.get('is_bookmark', '').lower()
@ -154,7 +154,7 @@ class MiddleVideoCollectionListView(generics.ListAPIView):
return VideoCollection.objects.filter(
status=True,
display_position=VideoCollection.DisplayPosition.MIDDLE
).order_by('order')
).order_by('order', '-created_at')
def list(self, request, *args, **kwargs):

Loading…
Cancel
Save