sortable — Making objects sortable¶
To make a model sortable, you need the following two additions to your model:
- You need to inherit from
SortableBase
(an abstract model) instead ofdjango.db.Model
, - You need to create a subclass of
SortableItemQuerySet
and attach that subclass as a queryset for your model.
Example:
from django_cradmin.sortable.models import SortableBase
from django_cradmin.sortable.models import SortableQuerySetBase
class MySortableItemQuerySet(SortableQuerySetBase):
parent_attribute = 'container'
class MySortableItem(SortableBase):
objects = MySortableItemQuerySet.as_manager()
container = models.ForeignKey(ItemContainer, blank=False, null=False)
name = models.CharField(...)
The class that inherits SortableBase
gets an attribute sort_index
. If you want the default ordering
for this model to be this attribute, you should add the following meta option on the model:
class Meta:
ordering = ['sort_index']
How to sort¶
Sorting is done by using these methods:
django_cradmin.sortable.models.SortableQuerySetBase.sort_before()
django_cradmin.sortable.models.SortableQuerySetBase.sort_last()
django_cradmin.sortable.models.SortableQuerySetBase.set_newitem_sort_index_to_last()
Example:
# Make a new item and put it last in the list
myitem = MySortableItem(container=somecontainer, name='Some name')
MySortableItem.objects.set_newitem_sort_index_to_last(myitem)
myitem.save()
# Move the given item before the item with id 777
# NOTE: Unlike set_newitem_sort_index_to_last(), sort_before() and sort_last()
# saves the item.
MySortableItem.objects.sort_before(someitem, sort_before_id=777)
# Move the given item last in the list
MySortableItem.objects.sort_last(someitem)
# ... or ...
MySortableItem.objects.sort_before(someitem, sort_before_id=None)
Makin an Admin UI that automatically adds items last in parent¶
Making an Admin UI that automatically adds items last in parent is easy. Just extend
django_cradmin.sortable.admin.SortableModelAdmin
instead of
django.contrib.admin.ModelAdmin
:
from django_cradmin.sortable.admin import SortableModelAdmin
class MySortableItemAdmin(SortableModelAdmin):
pass
admin.site.register(models.MySortableItem, MySortableItemAdmin)
You may also want to show the sort order by default in the admin UI listing, with something like this:
class MySortableItemAdmin(SortableModelAdmin):
ordering = ['container__name', 'sort_index']
API¶
-
class
SortableQuerySetBase
(model=None, query=None, using=None, hints=None)¶ Bases:
django_cradmin.utils.nulls_last_queryset.NullsLastQuerySet
QuerySet for
SortableManagerBase
.You must use this as a base class if you want to create a custom queryset class for models extending
SortableBase
.-
set_newitem_sort_index_to_last
(item, none_values_order_by=None)¶ Sets
item.sort_index
to the sort_index of the last item in the parent + 1. Does not save.ONLY USE THIS FOR NEWLY CREATED ITEMS.
-
sort_before
(item, sort_before_id, none_values_order_by=None)¶ Sort a given item before the item with id sort_before_id, or last if sort_before_id is
None
.Fetches all items in the same container, and makes changes in the ordering. Only the required updates are made.
-
sort_last
(item, none_values_order_by=None)¶ Just a shortcut for:
self.sort_before(item, sort_before_id=None)
-
-
class
SortableBase
(*args, **kwargs)¶ Bases:
django.db.models.base.Model
Used with
SortableQuerySetBase
to make models sortable.-
sort_index
¶ Sort index -
0
or higher.
-
-
class
SortableModelAdmin
(model, admin_site)¶ Bases:
django.contrib.admin.options.ModelAdmin
ModelAdmin that automatically sets the
sort_index
of newly added items last in their parent. It also makessort_index
read-only by default.Used just like
django.contrib.admin.ModelAdmin
.-
make_sort_index_readonly
= False¶ If this is
True
, we make thesort_index
field read-only. Override this to avoid this magic (typically for debugging).
-
save_model
(request, obj, form, change)¶ Overridden to set the sortindex on save if the pk is None.
-
get_readonly_fields
(request, obj=None)¶ Overridden to make the sortindex readonly if
make_sort_index_readonly
isTrue
.
-