"""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}),)}, ), )