Use separate URLs per model in administration to do the sorting
- Correctly check if current user has permissions to made the change Fixes #142
This commit is contained in:
+48
-23
@@ -13,18 +13,21 @@ except ImportError:
|
||||
from django.contrib.admin import ModelAdmin, TabularInline, StackedInline
|
||||
from django.contrib.admin.options import InlineModelAdmin
|
||||
|
||||
if VERSION >= (1, 8):
|
||||
from django.contrib.auth import get_permission_codename
|
||||
try:
|
||||
from django.contrib.contenttypes.admin import (GenericStackedInline,
|
||||
GenericTabularInline)
|
||||
else:
|
||||
GenericTabularInline)
|
||||
except:
|
||||
# Django < 1.7
|
||||
from django.contrib.contenttypes.generic import (GenericStackedInline,
|
||||
GenericTabularInline)
|
||||
GenericTabularInline)
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
from django.template.defaultfilters import capfirst
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.http import require_POST
|
||||
|
||||
from adminsortable.fields import SortableForeignKey
|
||||
from adminsortable.models import SortableMixin
|
||||
@@ -82,18 +85,33 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
||||
|
||||
def get_urls(self):
|
||||
urls = super(SortableAdmin, self).get_urls()
|
||||
opts = self.model._meta
|
||||
try:
|
||||
info = opts.app_label, opts.model_name
|
||||
except AttributeError:
|
||||
# Django < 1.7
|
||||
info = opts.app_label, opts.modul_name
|
||||
|
||||
# this ajax view changes the order
|
||||
admin_do_sorting_url = url(r'^sorting/do-sorting/(?P<model_type_id>\d+)/$',
|
||||
# this ajax view changes the order of instances of self.model
|
||||
admin_do_sorting_url = url(
|
||||
r'^sort/do-sorting/$',
|
||||
self.admin_site.admin_view(self.do_sorting_view),
|
||||
name='admin_do_sorting')
|
||||
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+)/$',
|
||||
self.admin_site.admin_view(self.do_sorting_view),
|
||||
name='%s_%s_do_sorting' % info)
|
||||
|
||||
# this view displays the sortable objects
|
||||
admin_sort_url = url(r'^sort/$',
|
||||
admin_sort_url = url(
|
||||
r'^sort/$',
|
||||
self.admin_site.admin_view(self.sort_view),
|
||||
name='admin_sort')
|
||||
name='%s_%s_sort' % info)
|
||||
|
||||
urls = [
|
||||
admin_do_inline_sorting_url,
|
||||
admin_do_sorting_url,
|
||||
admin_sort_url
|
||||
] + urls
|
||||
@@ -104,15 +122,10 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
||||
Custom admin view that displays the objects as a list whose sort
|
||||
order can be changed via drag-and-drop.
|
||||
"""
|
||||
if not self.has_change_permission(request):
|
||||
raise PermissionDenied
|
||||
|
||||
opts = self.model._meta
|
||||
if VERSION >= (1, 8):
|
||||
codename = get_permission_codename('change', opts)
|
||||
has_perm = request.user.has_perm('{0}.{1}'.format(opts.app_label,
|
||||
codename))
|
||||
else:
|
||||
has_perm = request.user.has_perm('{0}.{1}'.format(opts.app_label,
|
||||
opts.get_change_permission()))
|
||||
|
||||
jquery_lib_path = 'admin/js/jquery.js' if VERSION < (1, 9) \
|
||||
else 'admin/js/vendor/jquery/jquery.js'
|
||||
@@ -202,7 +215,7 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
||||
capfirst(verbose_name_plural)),
|
||||
'opts': opts,
|
||||
'app_label': opts.app_label,
|
||||
'has_perm': has_perm,
|
||||
'has_perm': True,
|
||||
'objects': objects,
|
||||
'group_expression': sortable_by_expression,
|
||||
'sortable_by_class': sortable_by_class,
|
||||
@@ -258,19 +271,31 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
||||
return super(SortableAdmin, self).change_view(request, object_id,
|
||||
form_url='', extra_context=extra_context)
|
||||
|
||||
@method_decorator(require_POST)
|
||||
def do_sorting_view(self, request, model_type_id=None):
|
||||
"""
|
||||
This view sets the ordering of the objects for the model type
|
||||
and primary keys passed in. It must be an Ajax POST.
|
||||
"""
|
||||
if not self.has_change_permission(request):
|
||||
raise PermissionDenied
|
||||
|
||||
response = {'objects_sorted': False}
|
||||
|
||||
if request.is_ajax() and request.method == 'POST':
|
||||
if request.is_ajax():
|
||||
try:
|
||||
if model_type_id is None:
|
||||
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,
|
||||
request.POST.get('indexes', []).split(',')))
|
||||
klass = ContentType.objects.get(
|
||||
id=model_type_id).model_class()
|
||||
objects_dict = dict([(str(obj.pk), obj) for obj in
|
||||
klass.objects.filter(pk__in=indexes)])
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% load i18n admin_modify adminsortable_tags %}
|
||||
{% load i18n admin_modify adminsortable_tags admin_urls %}
|
||||
{% load static from staticfiles %}
|
||||
<div class="inline-group" id="{{ inline_admin_formset.formset.prefix }}-group">
|
||||
<h2>{{ inline_admin_formset.opts.verbose_name_plural|title }} {% if inline_admin_formset.formset.initial_form_count > 1 %} - {% trans "drag and drop to change order" %}{% endif %}</h2>
|
||||
@@ -17,7 +17,7 @@
|
||||
{% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
|
||||
{{ inline_admin_form.fk_field.field }}
|
||||
{% if inline_admin_form.original %}
|
||||
<input type="hidden" name="admin_sorting_url" value="{% url 'admin:admin_do_sorting' inline_admin_form.original.model_type_id %}" />
|
||||
<input type="hidden" name="admin_sorting_url" value="{% url opts|admin_urlname:'do_sorting' inline_admin_form.original.model_type_id %}" />
|
||||
{% endif %}
|
||||
</div>{% endfor %}
|
||||
</div>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
{% include "adminsortable/shared/fieldset.html" with inline_admin_form_forloop=forloop.parentloop initial_forms_count=inline_admin_formset.formset.management_form.initial.INITIAL_FORMS %}
|
||||
{% endfor %}
|
||||
{% if inline_admin_form.original %}
|
||||
<input type="hidden" name="admin_sorting_url" value="{% url 'admin:admin_do_sorting' inline_admin_form.original.model_type_id %}" />
|
||||
<input type="hidden" name="admin_sorting_url" value="{% url opts|admin_urlname:'do_sorting' inline_admin_form.original.model_type_id %}" />
|
||||
{% endif %}
|
||||
{% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
|
||||
{{ inline_admin_form.fk_field.field }}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% load i18n admin_modify adminsortable_tags %}
|
||||
{% load i18n admin_modify adminsortable_tags admin_urls %}
|
||||
{% load static from staticfiles %}
|
||||
<div class="inline-group" id="{{ inline_admin_formset.formset.prefix }}-group">
|
||||
<div class="tabular inline-related {% if forloop.last %}last-related{% endif %}">
|
||||
@@ -41,7 +41,7 @@
|
||||
{% endfor %}
|
||||
{% endspaceless %}
|
||||
{% if inline_admin_form.original %}
|
||||
<input type="hidden" name="admin_sorting_url" value="{% url 'admin:admin_do_sorting' inline_admin_form.original.model_type_id %}" />
|
||||
<input type="hidden" name="admin_sorting_url" value="{% url opts|admin_urlname:'do_sorting' inline_admin_form.original.model_type_id %}" />
|
||||
{% endif %}
|
||||
</td>
|
||||
{% for fieldset in inline_admin_form %}
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
{% endfor %}
|
||||
{% endspaceless %}
|
||||
{% if inline_admin_form.original %}
|
||||
<input type="hidden" name="admin_sorting_url" value="{% url 'admin:admin_do_sorting' inline_admin_form.original.model_type_id %}" />
|
||||
<input type="hidden" name="admin_sorting_url" value="{% url opts|admin_urlname:'do_sorting' inline_admin_form.original.model_type_id %}" />
|
||||
{% endif %}
|
||||
</td>
|
||||
{% for fieldset in inline_admin_form %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% load adminsortable_tags %}
|
||||
{% load adminsortable_tags admin_urls %}
|
||||
|
||||
<form>
|
||||
<input name="pk" type="hidden" value="{{ object.pk }}" />
|
||||
<a href="{% url 'admin:admin_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>
|
||||
<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>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user