Merge branch 'develop'
commit
b96896d890
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[](https://travis-ci.org/iambrandontaylor/django-admin-sortable)
|
[](https://travis-ci.org/iambrandontaylor/django-admin-sortable)
|
||||||
|
|
||||||
Current version: 2.0.20
|
Current version: 2.0.21
|
||||||
|
|
||||||
This project makes it easy to add drag-and-drop ordering to any model in
|
This project makes it easy to add drag-and-drop ordering to any model in
|
||||||
Django admin. Inlines for a sortable model may also be made sortable,
|
Django admin. Inlines for a sortable model may also be made sortable,
|
||||||
|
|
@ -500,8 +500,8 @@ ordering on top of that just seemed a little much in my opinion.
|
||||||
### Status
|
### Status
|
||||||
django-admin-sortable is currently used in production.
|
django-admin-sortable is currently used in production.
|
||||||
|
|
||||||
### What's new in 2.0.20?
|
### What's new in 2.0.21?
|
||||||
- Support for models that use another type of field besides `AutoField` for their primary key. Thanks [@rubendura](https://github.com/rubendura).
|
- Fixed a regression introduced by [ Pull Request 143](https://github.com/iambrandontaylor/django-admin-sortable/pull/143) which caused models sortable by a foriegn key to not persist the sort order correctly.
|
||||||
|
|
||||||
### Future
|
### Future
|
||||||
- Better template support for foreign keys that are self referential. If someone would like to take on rendering recursive sortables, that would be super.
|
- Better template support for foreign keys that are self referential. If someone would like to take on rendering recursive sortables, that would be super.
|
||||||
|
|
|
||||||
11
README.rst
11
README.rst
|
|
@ -3,7 +3,7 @@ Django Admin Sortable
|
||||||
|
|
||||||
|Build Status|
|
|Build Status|
|
||||||
|
|
||||||
Current version: 2.0.20
|
Current version: 2.0.21
|
||||||
|
|
||||||
This project makes it easy to add drag-and-drop ordering to any model in
|
This project makes it easy to add drag-and-drop ordering to any model in
|
||||||
Django admin. Inlines for a sortable model may also be made sortable,
|
Django admin. Inlines for a sortable model may also be made sortable,
|
||||||
|
|
@ -617,12 +617,13 @@ Status
|
||||||
|
|
||||||
django-admin-sortable is currently used in production.
|
django-admin-sortable is currently used in production.
|
||||||
|
|
||||||
What's new in 2.0.20?
|
What's new in 2.0.21?
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
- Support for models that use another type of field besides
|
- Fixed a regression introduced by `Pull Request
|
||||||
``AutoField`` for their primary key. Thanks
|
143 <https://github.com/iambrandontaylor/django-admin-sortable/pull/143>`__
|
||||||
[@rubendura](https://github.com/rubendura).
|
which caused models sortable by a foriegn key to not persist the sort
|
||||||
|
order correctly.
|
||||||
|
|
||||||
Future
|
Future
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
VERSION = (2, 0, 20)
|
VERSION = (2, 0, 21)
|
||||||
DEV_N = None
|
DEV_N = None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,16 +106,10 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
||||||
info = opts.app_label, opts.model_name
|
info = opts.app_label, opts.model_name
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# Django < 1.7
|
# Django < 1.7
|
||||||
info = opts.app_label, opts.modul_name
|
info = opts.app_label, opts.model_name
|
||||||
|
|
||||||
# this ajax view changes the order of instances of self.model
|
# this ajax view changes the order of instances of the model type
|
||||||
admin_do_sorting_url = url(
|
admin_do_sorting_url = url(
|
||||||
r'^sort/do-sorting/$',
|
|
||||||
self.admin_site.admin_view(self.do_sorting_view),
|
|
||||||
name='%s_%s_do_sorting' % info)
|
|
||||||
|
|
||||||
# this ajax view changes the order of instances of inline models
|
|
||||||
admin_do_inline_sorting_url = url(
|
|
||||||
r'^sort/do-sorting/(?P<model_type_id>\d+)/$',
|
r'^sort/do-sorting/(?P<model_type_id>\d+)/$',
|
||||||
self.admin_site.admin_view(self.do_sorting_view),
|
self.admin_site.admin_view(self.do_sorting_view),
|
||||||
name='%s_%s_do_sorting' % info)
|
name='%s_%s_do_sorting' % info)
|
||||||
|
|
@ -127,7 +121,6 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
||||||
name='%s_%s_sort' % info)
|
name='%s_%s_sort' % info)
|
||||||
|
|
||||||
urls = [
|
urls = [
|
||||||
admin_do_inline_sorting_url,
|
|
||||||
admin_do_sorting_url,
|
admin_do_sorting_url,
|
||||||
admin_sort_url
|
admin_sort_url
|
||||||
] + urls
|
] + urls
|
||||||
|
|
@ -280,15 +273,7 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
||||||
|
|
||||||
if request.is_ajax():
|
if request.is_ajax():
|
||||||
try:
|
try:
|
||||||
if model_type_id is None:
|
klass = ContentType.objects.get(id=model_type_id).model_class()
|
||||||
klass = self.model
|
|
||||||
else:
|
|
||||||
klass = get_object_or_404(ContentType,
|
|
||||||
id=model_type_id).model_class()
|
|
||||||
if klass not in (inline.model for inline in self.inlines):
|
|
||||||
raise Http404(
|
|
||||||
'There is no inline model with type id: {0}'.format(
|
|
||||||
model_type_id))
|
|
||||||
|
|
||||||
indexes = list(map(str,
|
indexes = list(map(str,
|
||||||
request.POST.get('indexes', []).split(',')))
|
request.POST.get('indexes', []).split(',')))
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@
|
||||||
|
|
||||||
<form>
|
<form>
|
||||||
<input name="pk" type="hidden" value="{{ object.pk }}" />
|
<input name="pk" type="hidden" value="{{ object.pk }}" />
|
||||||
<a href="{% url opts|admin_urlname:'do_sorting' %}" class="admin_sorting_url"><i class="fa fa-{% if forloop.first %}sort-desc{% elif forloop.last %}sort-asc{% else %}sort{% endif %}"></i> {{ object }}</a>
|
<a href="{% url opts|admin_urlname:'do_sorting' object.model_type_id %}" class="admin_sorting_url"><i class="fa fa-{% if forloop.first %}sort-desc{% elif forloop.last %}sort-asc{% else %}sort{% endif %}"></i> {{ object }}</a>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -123,10 +123,7 @@ class SortableTestCase(TestCase):
|
||||||
category3 = self.create_category(title='Category 3')
|
category3 = self.create_category(title='Category 3')
|
||||||
return category1, category2, category3
|
return category1, category2, category3
|
||||||
|
|
||||||
def get_sorting_url(self):
|
def get_sorting_url(self, model):
|
||||||
return '/admin/app/category/sort/do-sorting/'
|
|
||||||
|
|
||||||
def get_inline_sorting_url(self, model):
|
|
||||||
return '/admin/app/project/sort/do-sorting/{0}/'.format(
|
return '/admin/app/project/sort/do-sorting/{0}/'.format(
|
||||||
model.model_type_id())
|
model.model_type_id())
|
||||||
|
|
||||||
|
|
@ -155,7 +152,7 @@ class SortableTestCase(TestCase):
|
||||||
category1, category2, category3 = self.make_test_categories()
|
category1, category2, category3 = self.make_test_categories()
|
||||||
# make a normal GET
|
# make a normal GET
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
self.get_sorting_url(),
|
self.get_sorting_url(Category),
|
||||||
data=self.get_category_indexes(category1, category2, category3))
|
data=self.get_category_indexes(category1, category2, category3))
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
|
@ -171,7 +168,7 @@ class SortableTestCase(TestCase):
|
||||||
category1, category2, category3 = self.make_test_categories()
|
category1, category2, category3 = self.make_test_categories()
|
||||||
# make a normal POST
|
# make a normal POST
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
self.get_sorting_url(),
|
self.get_sorting_url(Category),
|
||||||
data=self.get_category_indexes(category1, category2, category3))
|
data=self.get_category_indexes(category1, category2, category3))
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
|
@ -186,7 +183,7 @@ class SortableTestCase(TestCase):
|
||||||
|
|
||||||
category1, category2, category3 = self.make_test_categories()
|
category1, category2, category3 = self.make_test_categories()
|
||||||
# make a normal POST
|
# make a normal POST
|
||||||
response = self.client.post(self.get_sorting_url(),
|
response = self.client.post(self.get_sorting_url(Category),
|
||||||
data=self.get_category_indexes(category1, category2, category3))
|
data=self.get_category_indexes(category1, category2, category3))
|
||||||
content = json.loads(response.content.decode(encoding='UTF-8'),
|
content = json.loads(response.content.decode(encoding='UTF-8'),
|
||||||
'latin-1')
|
'latin-1')
|
||||||
|
|
@ -202,7 +199,7 @@ class SortableTestCase(TestCase):
|
||||||
category1, category2, category3 = self.make_test_categories()
|
category1, category2, category3 = self.make_test_categories()
|
||||||
|
|
||||||
# make an Ajax POST
|
# make an Ajax POST
|
||||||
response = self.client.post(self.get_sorting_url(),
|
response = self.client.post(self.get_sorting_url(Category),
|
||||||
data=self.get_category_indexes(category3, category2, category1),
|
data=self.get_category_indexes(category3, category2, category1),
|
||||||
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||||
content = json.loads(response.content.decode(encoding='UTF-8'),
|
content = json.loads(response.content.decode(encoding='UTF-8'),
|
||||||
|
|
@ -273,27 +270,6 @@ class SortableTestCase(TestCase):
|
||||||
self.assertEquals(response.status_code, httplib.FORBIDDEN,
|
self.assertEquals(response.status_code, httplib.FORBIDDEN,
|
||||||
'Sort view must be forbidden.')
|
'Sort view must be forbidden.')
|
||||||
|
|
||||||
def test_adminsortable_inline_changelist_not_found(self):
|
|
||||||
self.client.login(username=self.user.username,
|
|
||||||
password=self.user_raw_password)
|
|
||||||
|
|
||||||
project = Project.objects.create(
|
|
||||||
category=self.create_category(),
|
|
||||||
description='Test project'
|
|
||||||
)
|
|
||||||
note1 = project.note_set.create(text='note 1')
|
|
||||||
note2 = project.note_set.create(text='note 2')
|
|
||||||
|
|
||||||
response = self.client.post(
|
|
||||||
self.get_inline_sorting_url(Category),
|
|
||||||
data=self.get_category_indexes(note2, note1),
|
|
||||||
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
|
||||||
|
|
||||||
self.assertEqual(
|
|
||||||
response.status_code,
|
|
||||||
httplib.NOT_FOUND,
|
|
||||||
'Categories must not be sortable trough ProjectAdmin')
|
|
||||||
|
|
||||||
def test_adminsortable_inline_changelist_success(self):
|
def test_adminsortable_inline_changelist_success(self):
|
||||||
self.client.login(username=self.user.username,
|
self.client.login(username=self.user.username,
|
||||||
password=self.user_raw_password)
|
password=self.user_raw_password)
|
||||||
|
|
@ -307,7 +283,7 @@ class SortableTestCase(TestCase):
|
||||||
note3 = project.note_set.create(text='note 3')
|
note3 = project.note_set.create(text='note 3')
|
||||||
|
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
self.get_inline_sorting_url(project.note_set.model),
|
self.get_sorting_url(project.note_set.model),
|
||||||
data=self.get_category_indexes(note3, note2, note1),
|
data=self.get_category_indexes(note3, note2, note1),
|
||||||
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue