{"id":3964,"library":"django-admin-sortable2","title":"django-admin-sortable2","description":"django-admin-sortable2 is a Django package that provides generic drag-and-drop ordering functionality for objects in the List, Stacked-Inline, and Tabular-Inline Views of the Django Admin interface. It enriches existing `ModelAdmin` and `InlineModelAdmin` classes with sortable behavior via mixins. The library is actively maintained, with frequent minor and patch releases to support newer Django and Python versions.","status":"active","version":"2.3.1","language":"en","source_language":"en","source_url":"https://github.com/jrief/django-admin-sortable2","tags":["django","admin","sortable","drag-and-drop","inline"],"install":[{"cmd":"pip install django-admin-sortable2","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Required for Django integration, minimum version 4.2.","package":"Django","optional":false}],"imports":[{"note":"Used to make a ModelAdmin's list view sortable.","symbol":"SortableAdminMixin","correct":"from adminsortable2.admin import SortableAdminMixin"},{"note":"General mixin for making StackedInline or TabularInline views sortable. Specific aliases like SortableStackedInline and SortableTabularInline are also available.","symbol":"SortableInlineAdminMixin","correct":"from adminsortable2.admin import SortableInlineAdminMixin"},{"note":"Required for custom inline formsets to ensure sorting is handled correctly.","symbol":"CustomInlineFormSet","correct":"from adminsortable2.admin import CustomInlineFormSet"}],"quickstart":{"code":"import os\n\n# settings.py\n# INSTALLED_APPS = [\n#     ...,\n#     'adminsortable2',\n#     'your_app_name',\n# ]\n\n# your_app_name/models.py\nfrom django.db import models\n\nclass Category(models.Model):\n    name = models.CharField(max_length=100)\n    order = models.PositiveIntegerField(default=0, blank=False, null=False, db_index=True)\n\n    class Meta:\n        ordering = ['order']\n        verbose_name_plural = 'Categories'\n\n    def __str__(self):\n        return self.name\n\nclass Item(models.Model):\n    category = models.ForeignKey(Category, on_delete=models.CASCADE)\n    name = models.CharField(max_length=100)\n    order = models.PositiveIntegerField(default=0, blank=False, null=False, db_index=True)\n\n    class Meta:\n        ordering = ['order']\n\n    def __str__(self):\n        return self.name\n\n# your_app_name/admin.py\nfrom django.contrib import admin\nfrom adminsortable2.admin import SortableAdminMixin, SortableTabularInline\nfrom .models import Category, Item\n\nclass ItemInline(SortableTabularInline):\n    model = Item\n    extra = 1\n    fields = ['name', 'order'] # 'order' can be omitted from 'fields' to be hidden\n\n@admin.register(Category)\nclass CategoryAdmin(SortableAdminMixin, admin.ModelAdmin):\n    list_display = ['name', 'order']\n    inlines = [ItemInline]\n\n# To run the example (after creating a Django project):\n# 1. Add 'adminsortable2' and 'your_app_name' to INSTALLED_APPS in settings.py.\n# 2. Run: python manage.py makemigrations your_app_name\n# 3. Run: python manage.py migrate\n# 4. Run: python manage.py createsuperuser\n# 5. Run: python manage.py runserver\n# 6. Access /admin/ and navigate to 'Categories' to test sorting.","lang":"python","description":"This quickstart demonstrates how to make both a main ModelAdmin list view and its associated inline forms sortable. It requires adding `adminsortable2` to `INSTALLED_APPS`, defining a positive integer `order` field (with `default=0` and in `Meta.ordering`) in your models, and then applying `SortableAdminMixin` to your `ModelAdmin` and `SortableTabularInline` (or `SortableStackedInline`) to your inline admin classes. Remember to run `makemigrations` and `migrate` after defining your models."},"warnings":[{"fix":"Review the official documentation for migration guidelines when upgrading from 1.x. Ensure your Django version is 4.2 or higher, and Python is 3.9 or higher.","message":"Version 2.0 introduced significant breaking changes, including replacing jQuery-UI with Sortable.js, removing extended Django admin templates, and dropping support for older Django (<=3.2) and Python (2.7, 3.4, 3.5) versions. Projects upgrading from 1.x must thoroughly review their code and update dependencies.","severity":"breaking","affected_versions":"< 2.0"},{"fix":"Ensure your sortable model has `order = models.PositiveIntegerField(default=0, blank=False, null=False, db_index=True)` and `class Meta: ordering = ['order']`.","message":"The model that you wish to make sortable must include a `PositiveIntegerField` for ordering (e.g., `order`) with `default=0`. This field must be the first element in the model's `Meta.ordering` tuple or list. For optimal performance, add `db_index=True`, and ensure it is not set to `editable=False`.","severity":"gotcha","affected_versions":"All"},{"fix":"After adding the order field, run the management command `./manage.py reorder <app_label.ModelName>` to automatically populate the `order` field for all existing instances.","message":"When applying `django-admin-sortable2` to existing models, the `order` field for existing objects might be `0` or `null`, preventing proper sorting.","severity":"gotcha","affected_versions":"All"},{"fix":"Inform users that they must click the 'Save' button on the parent model's detail page after reordering inline items.","message":"When reordering items within `StackedInline` or `TabularInline` views, the changes are not immediately saved to the database. The new order will only persist after the parent model's form is explicitly saved.","severity":"gotcha","affected_versions":"All"},{"fix":"Update your custom inline formset class to inherit from `CustomInlineFormSet`, e.g., `class MyCustomFormSet(CustomInlineFormSet, BaseInlineFormSet): ...`","message":"If you use a custom `formset` for your `SortableInlineAdminMixin` (e.g., `SortableTabularInline` or `SortableStackedInline`), that custom formset must inherit from `adminsortable2.admin.CustomInlineFormSet` in addition to `BaseInlineFormSet` to ensure sorting functionality works correctly.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}