In my case, here is the solution (maybe someone needs a reference applying what @armstrove said):
# models.py
class PagexElement(models.Model):
"""Smallest reusable building block for page construction. Elements contain HTML templates with placeholders that can be customized when used in pages. One or more elements compose a section."""
...
class PagexSection(models.Model):
"""Collection of elements that form a reusable section. Sections are composed of one or more elements and define the structure for page layouts."""
...
class PagexInterSectElem(models.Model):
"""Intermediary model to handle the ordering of elements within a section. Allows the same element to appear in different positions across sections."""
...
class Meta:
unique_together = [["section", "element", "order"]]
# admin.py
from adminsortable2.admin import SortableAdminBase, SortableInlineAdminMixin
from django.contrib import admin
from . import forms, models
...
class PagexInterSectElemInline(SortableInlineAdminMixin, admin.TabularInline):
model = models.PagexInterSectElem
formset = forms.PagexInterSectElemFormSet
...
@admin.register(models.PagexSection)
class PagexSectionAdmin(SortableAdminBase, admin.ModelAdmin):
"""Customizes the management of layout sections."""
...
# forms.py
from adminsortable2 import admin
from django import forms
...
class PagexInterSectElemFormSet(admin.CustomInlineFormSet, forms.BaseInlineFormSet):
"""Custom formset that allows duplicate elements in different section positions."""
def validate_unique(self):
# Skip the default unique validation for 'element' field! Pagex only cares about section+order uniqueness (handled by DB constraint)!
super().validate_unique()
def _validate_unique_for_date_fields(self):
# Override to prevent element uniqueness validation!
pass
Cheers.