Sortables

Currently Django Suit supports three types of sortables:

  1. Sortable for change list
  2. Sortable for django-mptt tree list
  3. Sortable for tabular inlines

Limitations

Since sortables are based on JavaScript solution, there are known limitations:

  1. They doesn’t work with pagination.
  2. You won’t be able to use different list order other, than by sortable parameter.

Under the hood

Widgets add sortable parameter to list_editable fields as simple number inputs. Afterwards JavaScript utils replaces these editable inputs with arrows. Order is not saved instantly, but only when user saves form, which is very handy - user can do sorting first and afterwards save it or cancel if changed his mind.

Change list sortable

To use change list sortable you must do following:

  1. In your models.py file add integer property for sortable to you model:

    from django.db import models
    
    class Continent(models.Model):
        ...
        order = models.PositiveIntegerField()
    
  2. In your in your admin.py extend SortableModelAdmin class and specify sortable name:

    from suit.admin import SortableModelAdmin
    
    class ContinentAdmin(SortableModelAdmin):
        ...
        sortable = 'order'
    

That’s it, you should see similar picture to example below in your admin now.

Note

If you want sortable arrows to appear in different column than last, you can do this by adding sortable field to list_editable in desired order, for example: list_editable=('name', 'order', 'something'). If you set arrows as first column, you must also define list_display_links - because arrows can’t be displayed also as links.

Example

_images/changelist_sortable.png

Resources:

django-mptt tree sortable

To use sortable on djang-mptto tree, you must follow the same instructions as for change list sortable. Combining with documentation on django-mptt, final code should look like this:

  1. Prepare your model in models.py

    from django.db import models
    from mptt.fields import TreeForeignKey
    from mptt.models import MPTTModel
    
    class Category(MPTTModel):
        name = models.CharField(max_length=64)
        parent = TreeForeignKey('self', null=True, blank=True,
                                related_name='children')
    
        # Sortable property
        order = models.PositiveIntegerField()
    
        class MPTTMeta:
            order_insertion_by = ['order']
    
        # It is required to rebuild tree after save, when using order for mptt-tree
        def save(self, *args, **kwargs):
            super(Category, self).save(*args, **kwargs)
            Category.objects.rebuild()
    
        def __unicode__(self):
            return self.name
    
  2. Prepare admin class in admin.py:

    from suit.admin import SortableModelAdmin
    from mptt.admin import MPTTModelAdmin
    from .models import Category
    
    class CategoryAdmin(MPTTModelAdmin, SortableModelAdmin):
        mptt_level_indent = 20
        list_display = ('name', 'slug', 'is_active')
        list_editable = ('is_active',)
    
        # Specify name of sortable property
        sortable = 'order'
    
    admin.site.register(Category, CategoryAdmin)
    

Note

MPTTModelAdmin must be specified “before” SortableModelAdmin in extend syntax as shown in example.

Tabular inlines sortable

Currently inline sortable supports only TabularInline. Feel free to make a feature request on Github, if you think also StackedInline should be supported.

  1. In models.py your model for inlines, should have integer property for sortable, same way as described in all previous sortable examples:

    from django.db import models
    
    class Country(models.Model):
        ...
        order = models.PositiveIntegerField()
    
  2. In admin.py inline class must extend SortableModelAdmin class and specify sortable name:

    from django.contrib.admin import ModelAdmin
    from suit.admin import SortableModelAdmin
    
    class CountryInline(SortableTabularInline):
        model = Country
        sortable = 'order'
    
    class ContinentAdmin(ModelAdmin):
        inlines = (CountryInline,)
    

That’s it, you should see similar picture to example below in your admin now.

Table Of Contents

Previous topic

Widgets

This Page