Features: 1) Replace I18NTabTranslationAdmin with I18NFieldsetMixin for admin classes; 2) Introduce _TranslationInline for managing translation fields dynamically; 3) Add created and modified fields to readonly_fields in Category admin class;
Fixes: 1) Resolve unnecessary imports from `modeltranslation.admin` and streamline admin imports; Extra: 1) Refactor translation logic into `get_inline_instances` for improved modularity and clarity.
This commit is contained in:
parent
0d37b5b23b
commit
76c3cd17e3
1 changed files with 49 additions and 39 deletions
|
|
@ -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 <field>_<lang> 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",)
|
||||
|
|
|
|||
Loading…
Reference in a new issue