diff --git a/core/admin.py b/core/admin.py index 18f0a1fa..4ac578ee 100644 --- a/core/admin.py +++ b/core/admin.py @@ -4,13 +4,12 @@ from constance.admin import ConstanceAdmin as BaseConstanceAdmin from django.apps import apps from django.contrib import admin from django.contrib.admin import ModelAdmin, TabularInline +from django.contrib.admin.options import InlineModelAdmin from django.contrib.gis.admin import GISModelAdmin from django.db.models import Model +from django.forms import modelform_factory from django.urls import path from django.utils.translation import gettext_lazy as _ -from modeltranslation.admin import ( - TabbedExternalJqueryTranslationAdmin, -) from modeltranslation.translator import translator from modeltranslation.utils import get_translation_fields from mptt.admin import DraggableMPTTAdmin @@ -48,41 +47,50 @@ SECTION_RELATIONS = _("relations") class I18NFieldsetMixin: model: type[Model] - """ - Pulls all _ translation columns out of the regular - fieldsets and tucks them into one extra fieldset/tab called "I18N". - """ - - def get_fieldsets(self, request, obj=None): - base_fieldsets = super().get_fieldsets(request, obj) + def get_inline_instances(self, request, obj=None): + inlines = super().get_inline_instances(request, obj) trans_opts = translator.get_options_for_model(self.model) translation_fields = [] for orig in trans_opts.local_fields: - translation_fields.extend(get_translation_fields(orig)) + translation_fields += get_translation_fields(orig) - cleaned = [] - for title, opts in base_fieldsets: - original = list(opts.get("fields", [])) - filtered = [f for f in original if f not in translation_fields] - opts = opts.copy() - opts["fields"] = filtered - cleaned.append((title, opts)) - - cleaned.append( - ( - SECTION_I18N, - { - "classes": ("suit-tab-i18n",), - "fields": tuple(translation_fields), - }, + class _TranslationInline(InlineModelAdmin[self.model, self.model]): + model = self.model + form = modelform_factory( + self.model, + fields=translation_fields, + formfield_callback=lambda f, **kw: super( + I18NFieldsetMixin, self + ).formfield_for_dbfield(f, request, **kw), ) - ) - return cleaned + template = "admin/edit_inline/tabular.html" + is_navtab = True + verbose_name = _("translations") + verbose_name_plural = _("translations") + extra = 0 + def get_queryset(self, request): + return ( + self.model.objects.filter(pk=obj.pk) + if obj + else self.model.objects.none() + ) -class I18NTabTranslationAdmin(I18NFieldsetMixin, TabbedExternalJqueryTranslationAdmin): - pass + def get_formset(self, request, obj=None, **kw): + return super().get_formset( + request, + obj, + **{ + **kw, + "form": self.form, + "fields": translation_fields, + "exclude": [], + }, + ) + + inlines.append(_TranslationInline(self.model, self.admin_site)) + return inlines class BasicModelAdmin(ModelAdmin): @@ -121,7 +129,7 @@ class AttributeValueInline(TabularInline): @admin.register(AttributeGroup) -class AttributeGroupAdmin(BasicModelAdmin, I18NTabTranslationAdmin): +class AttributeGroupAdmin(BasicModelAdmin, I18NFieldsetMixin): list_display = ("name", "modified") search_fields = ( "uuid", @@ -144,7 +152,7 @@ class AttributeGroupAdmin(BasicModelAdmin, I18NTabTranslationAdmin): @admin.register(Attribute) -class AttributeAdmin(BasicModelAdmin, I18NTabTranslationAdmin): +class AttributeAdmin(BasicModelAdmin, I18NFieldsetMixin): list_display = ("name", "group", "value_type", "modified") list_filter = ("value_type", "group", "is_active") search_fields = ("uuid", "name", "group__name") @@ -152,7 +160,7 @@ class AttributeAdmin(BasicModelAdmin, I18NTabTranslationAdmin): @admin.register(AttributeValue) -class AttributeValueAdmin(BasicModelAdmin, I18NTabTranslationAdmin): +class AttributeValueAdmin(BasicModelAdmin, I18NFieldsetMixin): list_display = ("attribute", "value", "modified") list_filter = ("attribute__group", "is_active") search_fields = ("uuid", "value", "attribute__name") @@ -168,7 +176,7 @@ class CategoryChildrenInline(admin.TabularInline): @admin.register(Category) -class CategoryAdmin(DraggableMPTTAdmin, BasicModelAdmin, I18NTabTranslationAdmin): +class CategoryAdmin(DraggableMPTTAdmin, BasicModelAdmin, I18NFieldsetMixin): mptt_indent_field = "name" list_display = ("indented_title", "parent", "is_active", "modified") # noinspection PyUnresolvedReferences @@ -214,6 +222,8 @@ class CategoryAdmin(DraggableMPTTAdmin, BasicModelAdmin, I18NTabTranslationAdmin readonly_fields = ( "uuid", "slug", + "created", + "modified", ) def indented_title(self, instance): @@ -224,7 +234,7 @@ class CategoryAdmin(DraggableMPTTAdmin, BasicModelAdmin, I18NTabTranslationAdmin @admin.register(Brand) -class BrandAdmin(BasicModelAdmin, I18NTabTranslationAdmin): +class BrandAdmin(BasicModelAdmin, I18NFieldsetMixin): list_display = ("name",) list_filter = ("categories", "is_active") search_fields = ( @@ -255,7 +265,7 @@ class StockInline(TabularInline): @admin.register(Product) -class ProductAdmin(BasicModelAdmin, I18NTabTranslationAdmin): +class ProductAdmin(BasicModelAdmin, I18NFieldsetMixin): list_display = ( "name", "partnumber", @@ -340,13 +350,13 @@ class ProductAdmin(BasicModelAdmin, I18NTabTranslationAdmin): @admin.register(ProductTag) -class ProductTagAdmin(BasicModelAdmin, I18NTabTranslationAdmin): +class ProductTagAdmin(BasicModelAdmin, I18NFieldsetMixin): list_display = ("name",) search_fields = ("name",) @admin.register(CategoryTag) -class CategoryTagAdmin(BasicModelAdmin, I18NTabTranslationAdmin): +class CategoryTagAdmin(BasicModelAdmin, I18NFieldsetMixin): list_display = ("name",) search_fields = ("name",) @@ -458,7 +468,7 @@ class PromoCodeAdmin(BasicModelAdmin): @admin.register(Promotion) -class PromotionAdmin(BasicModelAdmin, I18NTabTranslationAdmin): +class PromotionAdmin(BasicModelAdmin, I18NFieldsetMixin): list_display = ("name", "discount_percent", "modified") search_fields = ("name",) autocomplete_fields = ("products",)