django-admin-sortable2
django-admin-sortable2 copied to clipboard
django-hashid-field integration
Hi, I'm encountering an error in the console logs on sorting management on a model with hashid which, however, does not seem to compromise the real functioning of sorting
Internal Server Error: /admin/projects/project/adminsortable2_update/
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/django/contrib/admin/sites.py", line 233, in inner
return view(request, *args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/adminsortable2/admin.py", line 247, in update_order
return HttpResponse(json.dumps(moved_items, cls=DjangoJSONEncoder), content_type='application/json;charset=UTF-8')
File "/usr/local/lib/python3.8/json/__init__.py", line 234, in dumps
return cls(
File "/usr/local/lib/python3.8/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/local/lib/python3.8/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/usr/local/lib/python3.8/site-packages/django/core/serializers/json.py", line 105, in default
return super().default(o)
File "/usr/local/lib/python3.8/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Hashid is not JSON serializable
The way this can be solved is to subclass SortableAdminMixin. The bad thing in this is we're only doing it because we need to use HashidJSONEncoder when we are returning the response. It would be much nicer to be able to override the encoder, or something along the lines of not having to redefine a whole method.
from adminsortable2.admin import SortableAdminMixin
from django.http.response import (
HttpResponse,
HttpResponseBadRequest,
HttpResponseForbidden,
HttpResponseNotAllowed,
)
class HashIdSortableAdminMixin(SortableAdminMixin):
"""A mixin enabling sorting functionalities."""
encoder = MyEncoder
def update_order(self, request):
"""Update items order."""
if not request.is_ajax() or request.method != "POST":
return HttpResponseBadRequest("Not an XMLHttpRequest")
if request.method != "POST":
return HttpResponseNotAllowed("Must be a POST request")
if not self.has_change_permission(request):
return HttpResponseForbidden("Missing permissions to perform this request")
startorder = int(request.POST.get("startorder"))
endorder = int(request.POST.get("endorder", 0))
moved_items = list(self._move_item(request, startorder, endorder))
return HttpResponse(
json.dumps(moved_items, cls=self.encoder),
content_type="application/json;charset=UTF-8",
)