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.
156 lines
5.1 KiB
156 lines
5.1 KiB
from django.contrib import admin
|
|
from django.utils.translation import gettext_lazy as _
|
|
from unfold.admin import ModelAdmin, TabularInline
|
|
from unfold.decorators import display
|
|
|
|
# Import your custom admin site
|
|
from utils.admin import project_admin_site
|
|
|
|
# Import your models
|
|
from ..models import (
|
|
BookReference,
|
|
BookReferenceImage,
|
|
BookAuthor,
|
|
BookAttribute
|
|
)
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# 1. Inlines
|
|
# -----------------------------------------------------------------------------
|
|
|
|
class BookReferenceImageInline(TabularInline):
|
|
"""
|
|
Inline for managing Book Images directly inside the BookReference page.
|
|
"""
|
|
model = BookReferenceImage
|
|
extra = 0
|
|
fields = ('image', 'order', 'description')
|
|
readonly_fields = ('created_at',)
|
|
|
|
|
|
class BookAttributeInline(TabularInline):
|
|
"""
|
|
Inline for managing Book Attributes (Key-Value pairs) inside BookReference.
|
|
"""
|
|
model = BookAttribute
|
|
extra = 0
|
|
fields = ('title', 'value')
|
|
readonly_fields = ('created_at',)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# 2. Main Admins
|
|
# -----------------------------------------------------------------------------
|
|
|
|
class BookReferenceAdmin(ModelAdmin):
|
|
"""Admin for BookReference model"""
|
|
|
|
# Use custom methods for JSON fields to show readable text
|
|
list_display = (
|
|
'get_title_display',
|
|
'slug',
|
|
'get_publisher_display',
|
|
'year_of_publication',
|
|
'rate',
|
|
'created_at'
|
|
)
|
|
|
|
list_filter = ('year_of_publication', 'rate', 'created_at')
|
|
|
|
# Searching by JSON fields via string is limited in Django,
|
|
# so we focus on standard fields
|
|
search_fields = ('isbn', 'slug', 'volume')
|
|
|
|
readonly_fields = ('created_at', 'updated_at')
|
|
|
|
# Add the inlines to manage images and attributes on the same page
|
|
inlines = [BookReferenceImageInline, BookAttributeInline]
|
|
|
|
fieldsets = (
|
|
(_('Basic Info'), {
|
|
'fields': ('title', 'description', 'slug', 'language')
|
|
}),
|
|
(_('Publication Info'), {
|
|
'fields': ('publisher', 'isbn', 'year_of_publication', 'number_page', 'volume')
|
|
}),
|
|
(_('Rating & Stats'), {
|
|
'fields': ('rate', 'created_at', 'updated_at')
|
|
}),
|
|
)
|
|
|
|
# --- Custom Display Methods ---
|
|
|
|
@display(description=_('Title'), ordering='title')
|
|
def get_title_display(self, obj):
|
|
return self._extract_first_text(obj.title)
|
|
|
|
@display(description=_('Publisher'))
|
|
def get_publisher_display(self, obj):
|
|
return self._extract_first_text(obj.publisher)
|
|
|
|
def _extract_first_text(self, json_data):
|
|
"""Helper to safely extract the first 'text' from a JSON list"""
|
|
if json_data and isinstance(json_data, list) and len(json_data) > 0:
|
|
first_item = json_data[0]
|
|
if isinstance(first_item, dict):
|
|
return first_item.get('text', '-')
|
|
return '-'
|
|
|
|
|
|
class BookAuthorAdmin(ModelAdmin):
|
|
"""Admin for BookAuthor model"""
|
|
|
|
list_display = ('get_name_display', 'created_at', 'updated_at')
|
|
search_fields = ('name',) # Note: Search works best on exact text matches
|
|
readonly_fields = ('created_at', 'updated_at')
|
|
|
|
# Use filter_horizontal for ManyToMany fields to make selection easier
|
|
filter_horizontal = ('book_references',)
|
|
|
|
@display(description=_('Name'), ordering='name')
|
|
def get_name_display(self, obj):
|
|
if obj.name and isinstance(obj.name, list) and len(obj.name) > 0:
|
|
first = obj.name[0]
|
|
if isinstance(first, dict):
|
|
return first.get('text', '-')
|
|
return '-'
|
|
|
|
|
|
class BookAttributeAdmin(ModelAdmin):
|
|
"""
|
|
Admin for managing Attributes independently.
|
|
Useful if you want to see all attributes across all books.
|
|
"""
|
|
list_display = ('get_title_display', 'get_value_display', 'get_book_display', 'created_at')
|
|
list_filter = ('created_at',)
|
|
search_fields = ('book_reference__slug',)
|
|
|
|
@display(description=_('Title'), ordering='title')
|
|
def get_title_display(self, obj):
|
|
return self._extract_first_text(obj.title)
|
|
|
|
@display(description=_('Value'), ordering='value')
|
|
def get_value_display(self, obj):
|
|
return self._extract_first_text(obj.value)
|
|
|
|
@display(description=_('Book Reference'), ordering='book_reference')
|
|
def get_book_display(self, obj):
|
|
if obj.book_reference:
|
|
return self._extract_first_text(obj.book_reference.title)
|
|
return '-'
|
|
|
|
def _extract_first_text(self, json_data):
|
|
if json_data and isinstance(json_data, list) and len(json_data) > 0:
|
|
first = json_data[0]
|
|
if isinstance(first, dict):
|
|
return first.get('text', '-')
|
|
return '-'
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# 3. Registration
|
|
# -----------------------------------------------------------------------------
|
|
|
|
project_admin_site.register(BookReference, BookReferenceAdmin)
|
|
project_admin_site.register(BookAuthor, BookAuthorAdmin)
|
|
project_admin_site.register(BookAttribute, BookAttributeAdmin)
|