django-categories/categories/admin.py
2024-04-17 12:18:12 +02:00

106 lines
3.4 KiB
Python

"""Admin interface classes."""
from django import forms
from django.contrib import admin
from django.utils.translation import gettext_lazy as _
from .base import CategoryBaseAdmin, CategoryBaseAdminForm
from .genericcollection import GenericCollectionTabularInline
from .models import Category
from .settings import JAVASCRIPT_URL, MODEL_REGISTRY, REGISTER_ADMIN, RELATION_MODELS
class NullTreeNodeChoiceField(forms.ModelChoiceField):
"""A ModelChoiceField for tree nodes."""
def __init__(self, level_indicator="---", *args, **kwargs):
self.level_indicator = level_indicator
super(NullTreeNodeChoiceField, self).__init__(*args, **kwargs)
def label_from_instance(self, obj) -> str:
"""
Creates labels which represent the tree level of each node when generating option labels.
"""
return "%s %s" % (self.level_indicator * getattr(obj, obj._mptt_meta.level_attr), obj)
if RELATION_MODELS:
from .models import CategoryRelation
class InlineCategoryRelation(GenericCollectionTabularInline):
"""The inline admin panel for category relations."""
model = CategoryRelation
class CategoryAdminForm(CategoryBaseAdminForm):
"""The form for a category in the admin."""
class Meta:
model = Category
fields = "__all__"
def clean_alternate_title(self) -> str:
"""Return either the name or alternate title for the category."""
if self.instance is None or not self.cleaned_data["alternate_title"]:
return self.cleaned_data["name"]
else:
return self.cleaned_data["alternate_title"]
class CategoryAdmin(CategoryBaseAdmin):
"""Admin for categories."""
form = CategoryAdminForm
list_display = ("name", "alternate_title", "active")
fieldsets = (
(None, {"fields": ("parent", "name", "thumbnail", "active")}),
(
_("Meta Data"),
{
"fields": ("alternate_title", "alternate_url", "description", "meta_keywords", "meta_extra"),
"classes": ("collapse",),
},
),
(
_("Advanced"),
{
"fields": ("order", "slug"),
"classes": ("collapse",),
},
),
)
autocomplete_fields = ("parent",)
if RELATION_MODELS:
inlines = [
InlineCategoryRelation,
]
class Media:
js = (JAVASCRIPT_URL + "genericcollections.js",)
if REGISTER_ADMIN:
admin.site.register(Category, CategoryAdmin)
for model, modeladmin in list(admin.site._registry.items()):
if model in list(MODEL_REGISTRY.values()) and modeladmin.fieldsets:
fieldsets = getattr(modeladmin, "fieldsets", ())
fields = [cat.split(".")[2] for cat in MODEL_REGISTRY if MODEL_REGISTRY[cat] == model]
# check each field to see if already defined
for cat in fields:
for k, v in fieldsets:
if cat in v["fields"]:
fields.remove(cat)
# if there are any fields left, add them under the categories fieldset
if len(fields) > 0:
admin.site.unregister(model)
admin.site.register(
model,
type(
"newadmin",
(modeladmin.__class__,),
{"fieldsets": fieldsets + (("Categories", {"fields": fields}),)},
),
)