You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
7.0 KiB
192 lines
7.0 KiB
from django.contrib import admin
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django.urls import reverse
|
|
from django.utils.html import format_html
|
|
from ajaxdatatable.admin import AjaxDatatable
|
|
|
|
from apps.library.models import *
|
|
|
|
|
|
@admin.register(Book)
|
|
class BookAdmin(AjaxDatatable):
|
|
list_display = ('title', 'slug', 'status', 'pin', 'file_type', 'view_count', 'created_at')
|
|
list_filter = ('status', 'pin', 'file_type', 'created_at', 'updated_at')
|
|
search_fields = ('title', 'slug', 'summary', 'description')
|
|
# autocomplete_fields = ('categories', 'collections', )
|
|
fieldsets = (
|
|
(None, {
|
|
'fields': ('title', 'slug', 'summary', 'description', 'thumbnail', 'pages_count')
|
|
}),
|
|
(_('Status'), {
|
|
'fields': ('status', 'pin')
|
|
}),
|
|
(_('File Information'), {
|
|
'fields': ('file_type', 'book_file')
|
|
}),
|
|
(_('Relations'), {
|
|
'fields': ('categories', 'collections')
|
|
}),
|
|
(_('Statistics'), {
|
|
'fields': ('view_count',)
|
|
}),
|
|
)
|
|
|
|
|
|
|
|
class BookCollectionAdminBase(AjaxDatatable):
|
|
"""Base admin class for all book collection types"""
|
|
list_display = ('get_title', 'status', 'order', 'count_books')
|
|
list_filter = ('status',)
|
|
search_fields = ('title',)
|
|
autocomplete_fields = ('books',)
|
|
ordering = ('order',)
|
|
|
|
fieldsets = (
|
|
(None, {
|
|
'fields': ('title', 'summary', 'status', 'order')
|
|
}),
|
|
(_('Books'), {
|
|
'fields': ('books',)
|
|
}),
|
|
)
|
|
|
|
exclude = ('display_position',)
|
|
|
|
def get_title(self, obj):
|
|
return str(obj.title)
|
|
get_title.short_description = _('Title')
|
|
|
|
|
|
@admin.display(description=_('Number of Books'))
|
|
def count_books(self, obj):
|
|
count = obj.books.count()
|
|
if count > 0:
|
|
url = reverse('admin:library_book_changelist') + f'?collections__id__exact={obj.id}'
|
|
return format_html('<a href="{}">{}</a>', url, count)
|
|
return count
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@admin.register(PinnedBookCollection)
|
|
class PinnedBookCollectionAdmin(BookCollectionAdminBase):
|
|
"""Admin for pinned book collections only"""
|
|
|
|
def get_queryset(self, request):
|
|
# Only show pinned collections
|
|
return super().get_queryset(request).filter(display_position=BookCollection.DisplayPosition.PINNED)
|
|
|
|
def save_model(self, request, obj, form, change):
|
|
# Ensure the display_position is always set to PINNED
|
|
obj.display_position = BookCollection.DisplayPosition.PINNED
|
|
super().save_model(request, obj, form, change)
|
|
|
|
|
|
@admin.register(MiddleBookCollection)
|
|
class MiddleBookCollectionAdmin(BookCollectionAdminBase):
|
|
"""Admin for middle section book collections only"""
|
|
|
|
def get_queryset(self, request):
|
|
# Only show middle section collections
|
|
return super().get_queryset(request).filter(display_position=BookCollection.DisplayPosition.MIDDLE)
|
|
|
|
def has_add_permission(self, request):
|
|
# Check if a middle collection already exists
|
|
exists = BookCollection.objects.filter(display_position=BookCollection.DisplayPosition.MIDDLE).exists()
|
|
# Only allow adding if no middle collection exists
|
|
return not exists
|
|
|
|
def has_delete_permission(self, request, obj=None):
|
|
# Prevent deletion of the middle collection
|
|
return False
|
|
|
|
def save_model(self, request, obj, form, change):
|
|
# Ensure the display_position is always set to MIDDLE
|
|
obj.display_position = BookCollection.DisplayPosition.MIDDLE
|
|
super().save_model(request, obj, form, change)
|
|
|
|
def changelist_view(self, request, extra_context=None):
|
|
# Check if a middle collection exists
|
|
try:
|
|
# Try to get the first (and should be only) middle collection
|
|
obj = self.get_queryset(request).first()
|
|
if obj:
|
|
# If it exists, redirect to the change view for this object
|
|
from django.http import HttpResponseRedirect
|
|
from django.urls import reverse
|
|
url = reverse(
|
|
'admin:%s_%s_change' % (obj._meta.app_label, obj._meta.model_name),
|
|
args=[obj.pk]
|
|
)
|
|
return HttpResponseRedirect(url)
|
|
except Exception:
|
|
# If any error occurs, just show the changelist view as usual
|
|
pass
|
|
|
|
# If no object exists or there was an error, show the default changelist view
|
|
return super().changelist_view(request, extra_context)
|
|
|
|
|
|
@admin.register(BottomBookCollection)
|
|
class BottomBookCollectionAdmin(BookCollectionAdminBase):
|
|
"""Admin for bottom section book collections only"""
|
|
|
|
def get_queryset(self, request):
|
|
# Only show bottom section collections
|
|
return super().get_queryset(request).filter(display_position=BookCollection.DisplayPosition.BOTTOM)
|
|
|
|
def has_add_permission(self, request):
|
|
# Check if a bottom collection already exists
|
|
exists = BookCollection.objects.filter(display_position=BookCollection.DisplayPosition.BOTTOM).exists()
|
|
# Only allow adding if no bottom collection exists
|
|
return not exists
|
|
|
|
def has_delete_permission(self, request, obj=None):
|
|
# Prevent deletion of the bottom collection
|
|
return False
|
|
|
|
def save_model(self, request, obj, form, change):
|
|
# Ensure the display_position is always set to BOTTOM
|
|
obj.display_position = BookCollection.DisplayPosition.BOTTOM
|
|
super().save_model(request, obj, form, change)
|
|
|
|
def changelist_view(self, request, extra_context=None):
|
|
# Check if a bottom collection exists
|
|
try:
|
|
# Try to get the first (and should be only) bottom collection
|
|
obj = self.get_queryset(request).first()
|
|
if obj:
|
|
# If it exists, redirect to the change view for this object
|
|
from django.http import HttpResponseRedirect
|
|
from django.urls import reverse
|
|
url = reverse(
|
|
'admin:%s_%s_change' % (obj._meta.app_label, obj._meta.model_name),
|
|
args=[obj.pk]
|
|
)
|
|
return HttpResponseRedirect(url)
|
|
except Exception:
|
|
# If any error occurs, just show the changelist view as usual
|
|
pass
|
|
|
|
# If no object exists or there was an error, show the default changelist view
|
|
return super().changelist_view(request, extra_context)
|
|
|
|
|
|
|
|
@admin.register(Category)
|
|
class CategoryAdmin(AjaxDatatable):
|
|
list_display = ('title', 'slug', 'status', 'count_books', 'created_at')
|
|
list_filter = ('status', 'created_at', 'updated_at')
|
|
search_fields = ('title', 'slug')
|
|
autocomplete_fields = ('books',)
|
|
|
|
@admin.display(description=_('Number of Books'))
|
|
def count_books(self, obj):
|
|
count = obj.books.count()
|
|
if count > 0:
|
|
url = reverse('admin:library_book_changelist') + f'?categories__id__exact={obj.id}'
|
|
return format_html('<a href="{}">{}</a>', url, count)
|
|
return count
|
|
|