7 changed files with 188 additions and 14 deletions
-
2apps/api/urls.py
-
156apps/hadis/admin/reference.py
-
15apps/hadis/admin/transmitter.py
-
5apps/hadis/models/hadis.py
-
13apps/hadis/models/reference.py
-
9apps/hadis/models/transmitter.py
-
2config/urls.py
@ -0,0 +1,156 @@ |
|||
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) |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue