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.apps import apps
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.admin import ModelAdmin, TabularInline
|
from django.contrib.admin import ModelAdmin, TabularInline
|
||||||
|
from django.contrib.admin.options import InlineModelAdmin
|
||||||
from django.contrib.gis.admin import GISModelAdmin
|
from django.contrib.gis.admin import GISModelAdmin
|
||||||
from django.db.models import Model
|
from django.db.models import Model
|
||||||
|
from django.forms import modelform_factory
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from modeltranslation.admin import (
|
|
||||||
TabbedExternalJqueryTranslationAdmin,
|
|
||||||
)
|
|
||||||
from modeltranslation.translator import translator
|
from modeltranslation.translator import translator
|
||||||
from modeltranslation.utils import get_translation_fields
|
from modeltranslation.utils import get_translation_fields
|
||||||
from mptt.admin import DraggableMPTTAdmin
|
from mptt.admin import DraggableMPTTAdmin
|
||||||
|
|
@ -48,41 +47,50 @@ SECTION_RELATIONS = _("relations")
|
||||||
|
|
||||||
class I18NFieldsetMixin:
|
class I18NFieldsetMixin:
|
||||||
model: type[Model]
|
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)
|
trans_opts = translator.get_options_for_model(self.model)
|
||||||
translation_fields = []
|
translation_fields = []
|
||||||
for orig in trans_opts.local_fields:
|
for orig in trans_opts.local_fields:
|
||||||
translation_fields.extend(get_translation_fields(orig))
|
translation_fields += get_translation_fields(orig)
|
||||||
|
|
||||||
cleaned = []
|
class _TranslationInline(InlineModelAdmin[self.model, self.model]):
|
||||||
for title, opts in base_fieldsets:
|
model = self.model
|
||||||
original = list(opts.get("fields", []))
|
form = modelform_factory(
|
||||||
filtered = [f for f in original if f not in translation_fields]
|
self.model,
|
||||||
opts = opts.copy()
|
fields=translation_fields,
|
||||||
opts["fields"] = filtered
|
formfield_callback=lambda f, **kw: super(
|
||||||
cleaned.append((title, opts))
|
I18NFieldsetMixin, self
|
||||||
|
).formfield_for_dbfield(f, request, **kw),
|
||||||
cleaned.append(
|
|
||||||
(
|
|
||||||
SECTION_I18N,
|
|
||||||
{
|
|
||||||
"classes": ("suit-tab-i18n",),
|
|
||||||
"fields": tuple(translation_fields),
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
)
|
template = "admin/edit_inline/tabular.html"
|
||||||
return cleaned
|
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):
|
def get_formset(self, request, obj=None, **kw):
|
||||||
pass
|
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):
|
class BasicModelAdmin(ModelAdmin):
|
||||||
|
|
@ -121,7 +129,7 @@ class AttributeValueInline(TabularInline):
|
||||||
|
|
||||||
|
|
||||||
@admin.register(AttributeGroup)
|
@admin.register(AttributeGroup)
|
||||||
class AttributeGroupAdmin(BasicModelAdmin, I18NTabTranslationAdmin):
|
class AttributeGroupAdmin(BasicModelAdmin, I18NFieldsetMixin):
|
||||||
list_display = ("name", "modified")
|
list_display = ("name", "modified")
|
||||||
search_fields = (
|
search_fields = (
|
||||||
"uuid",
|
"uuid",
|
||||||
|
|
@ -144,7 +152,7 @@ class AttributeGroupAdmin(BasicModelAdmin, I18NTabTranslationAdmin):
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Attribute)
|
@admin.register(Attribute)
|
||||||
class AttributeAdmin(BasicModelAdmin, I18NTabTranslationAdmin):
|
class AttributeAdmin(BasicModelAdmin, I18NFieldsetMixin):
|
||||||
list_display = ("name", "group", "value_type", "modified")
|
list_display = ("name", "group", "value_type", "modified")
|
||||||
list_filter = ("value_type", "group", "is_active")
|
list_filter = ("value_type", "group", "is_active")
|
||||||
search_fields = ("uuid", "name", "group__name")
|
search_fields = ("uuid", "name", "group__name")
|
||||||
|
|
@ -152,7 +160,7 @@ class AttributeAdmin(BasicModelAdmin, I18NTabTranslationAdmin):
|
||||||
|
|
||||||
|
|
||||||
@admin.register(AttributeValue)
|
@admin.register(AttributeValue)
|
||||||
class AttributeValueAdmin(BasicModelAdmin, I18NTabTranslationAdmin):
|
class AttributeValueAdmin(BasicModelAdmin, I18NFieldsetMixin):
|
||||||
list_display = ("attribute", "value", "modified")
|
list_display = ("attribute", "value", "modified")
|
||||||
list_filter = ("attribute__group", "is_active")
|
list_filter = ("attribute__group", "is_active")
|
||||||
search_fields = ("uuid", "value", "attribute__name")
|
search_fields = ("uuid", "value", "attribute__name")
|
||||||
|
|
@ -168,7 +176,7 @@ class CategoryChildrenInline(admin.TabularInline):
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Category)
|
@admin.register(Category)
|
||||||
class CategoryAdmin(DraggableMPTTAdmin, BasicModelAdmin, I18NTabTranslationAdmin):
|
class CategoryAdmin(DraggableMPTTAdmin, BasicModelAdmin, I18NFieldsetMixin):
|
||||||
mptt_indent_field = "name"
|
mptt_indent_field = "name"
|
||||||
list_display = ("indented_title", "parent", "is_active", "modified")
|
list_display = ("indented_title", "parent", "is_active", "modified")
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
|
|
@ -214,6 +222,8 @@ class CategoryAdmin(DraggableMPTTAdmin, BasicModelAdmin, I18NTabTranslationAdmin
|
||||||
readonly_fields = (
|
readonly_fields = (
|
||||||
"uuid",
|
"uuid",
|
||||||
"slug",
|
"slug",
|
||||||
|
"created",
|
||||||
|
"modified",
|
||||||
)
|
)
|
||||||
|
|
||||||
def indented_title(self, instance):
|
def indented_title(self, instance):
|
||||||
|
|
@ -224,7 +234,7 @@ class CategoryAdmin(DraggableMPTTAdmin, BasicModelAdmin, I18NTabTranslationAdmin
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Brand)
|
@admin.register(Brand)
|
||||||
class BrandAdmin(BasicModelAdmin, I18NTabTranslationAdmin):
|
class BrandAdmin(BasicModelAdmin, I18NFieldsetMixin):
|
||||||
list_display = ("name",)
|
list_display = ("name",)
|
||||||
list_filter = ("categories", "is_active")
|
list_filter = ("categories", "is_active")
|
||||||
search_fields = (
|
search_fields = (
|
||||||
|
|
@ -255,7 +265,7 @@ class StockInline(TabularInline):
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Product)
|
@admin.register(Product)
|
||||||
class ProductAdmin(BasicModelAdmin, I18NTabTranslationAdmin):
|
class ProductAdmin(BasicModelAdmin, I18NFieldsetMixin):
|
||||||
list_display = (
|
list_display = (
|
||||||
"name",
|
"name",
|
||||||
"partnumber",
|
"partnumber",
|
||||||
|
|
@ -340,13 +350,13 @@ class ProductAdmin(BasicModelAdmin, I18NTabTranslationAdmin):
|
||||||
|
|
||||||
|
|
||||||
@admin.register(ProductTag)
|
@admin.register(ProductTag)
|
||||||
class ProductTagAdmin(BasicModelAdmin, I18NTabTranslationAdmin):
|
class ProductTagAdmin(BasicModelAdmin, I18NFieldsetMixin):
|
||||||
list_display = ("name",)
|
list_display = ("name",)
|
||||||
search_fields = ("name",)
|
search_fields = ("name",)
|
||||||
|
|
||||||
|
|
||||||
@admin.register(CategoryTag)
|
@admin.register(CategoryTag)
|
||||||
class CategoryTagAdmin(BasicModelAdmin, I18NTabTranslationAdmin):
|
class CategoryTagAdmin(BasicModelAdmin, I18NFieldsetMixin):
|
||||||
list_display = ("name",)
|
list_display = ("name",)
|
||||||
search_fields = ("name",)
|
search_fields = ("name",)
|
||||||
|
|
||||||
|
|
@ -458,7 +468,7 @@ class PromoCodeAdmin(BasicModelAdmin):
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Promotion)
|
@admin.register(Promotion)
|
||||||
class PromotionAdmin(BasicModelAdmin, I18NTabTranslationAdmin):
|
class PromotionAdmin(BasicModelAdmin, I18NFieldsetMixin):
|
||||||
list_display = ("name", "discount_percent", "modified")
|
list_display = ("name", "discount_percent", "modified")
|
||||||
search_fields = ("name",)
|
search_fields = ("name",)
|
||||||
autocomplete_fields = ("products",)
|
autocomplete_fields = ("products",)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue