diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d626d44..0762b76 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,9 +5,14 @@ Changelog * Fixed: visual inconsistencies in grappelli tabular inline styles (`#136`_) * Fixed: numerous issues with django-polymorphic integration (`#138`_) +* Feature: Added ``SortableHiddenMixin`` akin to grappelli’s +`GrappelliSortableHiddenMixin`_ (`#123`_). Thanks `@brandenhall`_! .. _#136: https://github.com/theatlantic/django-nested-admin/issues/136 .. _#138: https://github.com/theatlantic/django-nested-admin/issues/138 +.. _GrappelliSortableHiddenMixin: https://django-grappelli.readthedocs.io/en/2.12.2/customization.html#grappellisortablehiddenmixin +.. _#123: https://github.com/theatlantic/django-nested-admin/pull/123 +.. @brandenhall_: https://github.com/brandenhall **3.2.2 (Apr 9, 2019)** diff --git a/docs/customization.rst b/docs/customization.rst index ba4d712..bc04d0c 100644 --- a/docs/customization.rst +++ b/docs/customization.rst @@ -9,6 +9,28 @@ Sortables The steps for enabling drag-and-drop sorting functionality is identical to Grappelli’s (even with the vanilla Django admin), so the `Grappelli documentation `_ for this feature is the best reference. This is equally true of sortables in Django Suit—do not follow Django Suit’s instructions for sortables, as they will not work. The `other features of Grappelli `_ have not been ported to work with vanilla Django, but in principle they should all still work with nested inlines using django-nested-admin if Grappelli is installed. If you run into any difficulty with this, please `create an issue `_ on this project’s Github. +If you want to have a sortable inline and also want to hide the field you're sorting, you can use ``SortableHiddenMixin``. Note that this mixin sets ``sortable_field_name`` to ``position`` by default (though this can be overridden by setting ``sortable_field_name`` on your inline class) and must be inherited prior to ``NestedStackedInline`` or ``NestedTabularInline``. + +.. code-block:: python + + import nested_admin + from django.contrib import admin + from .models import TableOfContents, TocArticle, TocSection + + class TocArticleInline(nested_admin.SortableHiddenMixin, + nested_admin.NestedStackedInline): + model = TocArticle + + class TocSectionInline(nested_admin.SortableHiddenMixin, + nested_admin.NestedStackedInline): + model = TocSection + inlines = [TocArticleInline] + + @admin.register(TableOfContents) + class TableOfContentsAdmin(nested_admin.NestedModelAdmin): + inlines = [TocSectionInline] + + Events ====== diff --git a/nested_admin/__init__.py b/nested_admin/__init__.py index 40e9873..40be2aa 100644 --- a/nested_admin/__init__.py +++ b/nested_admin/__init__.py @@ -22,6 +22,8 @@ # import mapping to objects in other modules all_by_module = { + 'nested_admin.forms': ( + 'SortableHiddenMixin'), 'nested_admin.formsets': ( 'NestedInlineFormSet', 'NestedBaseGenericInlineFormSet'), 'nested_admin.nested': ( @@ -42,7 +44,7 @@ 'NestedGenericStackedPolymorphicInline') # modules that should be imported when accessed as attributes of nested_admin -attribute_modules = frozenset(['formsets', 'nested', 'polymorphic']) +attribute_modules = frozenset(['forms', 'formsets', 'nested', 'polymorphic']) object_origins = {} for module, items in all_by_module.items(): diff --git a/nested_admin/forms.py b/nested_admin/forms.py new file mode 100644 index 0000000..9a07dea --- /dev/null +++ b/nested_admin/forms.py @@ -0,0 +1,18 @@ +from django.forms.widgets import HiddenInput + + +class SortableHiddenMixin(object): + """ + Enables inline sorting and hides the sortable field. + + By default it assumes the field name is ``position``. This can be + overridden by setting the ``sortable_field_name`` attribute to a + different value. + """ + sortable_field_name = "position" + + def formfield_for_dbfield(self, db_field, **kwargs): + if db_field.name == self.sortable_field_name: + kwargs["widget"] = HiddenInput() + return super(SortableHiddenMixin, self).formfield_for_dbfield( + db_field, **kwargs)