diff --git a/wagtailorderable/modeladmin/mixins.py b/wagtailorderable/modeladmin/mixins.py index 71388ae..fcfcf7e 100644 --- a/wagtailorderable/modeladmin/mixins.py +++ b/wagtailorderable/modeladmin/mixins.py @@ -12,6 +12,10 @@ from ..signals import pre_reorder, post_reorder +def ordering_contains_field(ordering, field_name): + return bool(set(ordering) & {field_name, "-" + field_name}) + + class OrderableMixinMetaClass(type): """ index_order method needs to be completed with an `admin_order_field` but as sort_order_field @@ -23,12 +27,16 @@ def __new__(cls, name, bases, attrs): if model and not sort_order_field: sort_order_field = getattr(model, 'sort_order_field', None) if sort_order_field: - # unfortunately, wagtail IndexView._get_default_ordering is currently using - # `model_admin.ordering` instead of `model_admin.get_ordering()` - # So we need to automagically set it here + # Ensure, that our sort field is set in "ordering", as this attribute is required by methods like + # wagtail's IndexView._get_default_ordering(). if 'ordering' not in attrs: - attrs['ordering'] = (sort_order_field, ) - elif sort_order_field not in attrs['ordering']: + opts = model._meta + if opts.ordering and ordering_contains_field(opts.ordering, sort_order_field): + # If the model's Meta already defines an ordering with our field, we use it. + attrs['ordering'] = opts.ordering + else: + attrs['ordering'] = (sort_order_field, ) + elif not ordering_contains_field(attrs['ordering'], sort_order_field): attrs['ordering'] = (sort_order_field, ) + tuple(attrs['ordering']) # set the "sorting" column @@ -79,17 +87,6 @@ def __init__(self, parent=None): "into your model." % (self.__class__.__name__, self.sort_order_field)) - def get_ordering(self, request): - """ - Returns a sequence defining the default ordering for results in the - list view. - """ - if not self.ordering: - return (self.sort_order_field, ) - elif self.sort_order_field not in self.ordering: - return (self.sort_order_field, ) + tuple(self.ordering) - return self.ordering - def get_list_display(self, request): """Add `index_order` as the first column to results""" list_display = list(super().get_list_display(request)) diff --git a/wagtailorderable/static/wagtailorderable/modeladmin/js/orderablemixin.js b/wagtailorderable/static/wagtailorderable/modeladmin/js/orderablemixin.js index 3123f49..922e077 100644 --- a/wagtailorderable/static/wagtailorderable/modeladmin/js/orderablemixin.js +++ b/wagtailorderable/static/wagtailorderable/modeladmin/js/orderablemixin.js @@ -5,7 +5,8 @@ $(function() { var sorted_cols = listing_thead.find('th.sorted'); order_header.find('a').addClass('text-replace').removeClass('icon icon-arrow-down-after icon-arrow-up-after'); order_header.find('a').html(' Sort'); - if(sorted_cols.length == 1 && order_header.hasClass('sorted') && order_header.hasClass('ascending')){ + if(sorted_cols.length === 1 && order_header.hasClass('sorted')){ + var isAsc = order_header.hasClass('ascending'); order_header.find('a').attr('title', 'Restore default list ordering').attr('href', '?'); listing_tbody.sortable({ cursor: "move", @@ -34,12 +35,12 @@ $(function() { if ($(this).data('idx') < ui.item.index()) { idx = $(movedElement).prev().data('object-pk'); if (idx) { - params.set('after', idx); + params.set(isAsc ? 'after' : 'before', idx); } } else if ($(this).data('idx') > ui.item.index()) { idx = $(movedElement).next().data('object-pk'); if (idx) { - params.set('before', idx); + params.set(isAsc ? 'before' : 'after', idx); } } @@ -66,6 +67,6 @@ $(function() { var href = new URL(window.location.href); // we need to keep current filters href.searchParams.set('o', '0'); a.attr('href', href.toString()); - order_header.removeClass('sorted ascending'); + order_header.removeClass('sorted ascending descending'); } });