Ticket #6903: 6903.4.diff

File 6903.4.diff, 13.0 KB (added by oinopion, 2 years ago)

Updated earlier patch by julien

  • django/contrib/admin/options.py

    diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
    index 34583eb..a8526b3 100644
    a b from django.contrib.admin.util import (unquote, flatten_fieldsets, get_deleted_o 
    1414from django.contrib.admin import validation
    1515from django.contrib.admin.templatetags.admin_static import static
    1616from django.contrib import messages
     17from django.utils.http import is_safe_url
    1718from django.views.decorators.csrf import csrf_protect
    1819from django.core.exceptions import PermissionDenied, ValidationError, FieldError
    1920from django.core.paginator import Paginator
    from django.utils.translation import ugettext as _ 
    3839from django.utils.translation import ungettext
    3940from django.utils.encoding import force_text
    4041
     42try:
     43    from urllib import parse as urllib_parse
     44except ImportError:     # Python 2
     45    import urllib as urllib_parse
     46    import urlparse
     47    urllib_parse.urlparse = urlparse.urlparse
     48
     49
    4150HORIZONTAL, VERTICAL = 1, 2
    4251# returns the <ul> class for a given radio_admin field
    4352get_ul_class = lambda x: 'radiolist%s' % (' inline' if x == HORIZONTAL else '')
    class ModelAdmin(BaseModelAdmin): 
    963972        when editing an existing object.
    964973        """
    965974        opts = self.model._meta
     975        changelist_url = reverse('admin:%s_%s_changelist' %
     976                                 (opts.app_label, opts.model_name),
     977                                 current_app=self.admin_site.name)
     978
     979        changelist_filters = request.POST.get('_changelist_filters')
     980        if changelist_filters:
     981            return HttpResponseRedirect(
     982                '%s?%s' % (changelist_url, changelist_filters))
     983
    966984        if self.has_change_permission(request, None):
    967             post_url = reverse('admin:%s_%s_changelist' %
    968                                (opts.app_label, opts.model_name),
    969                                current_app=self.admin_site.name)
     985            post_url = changelist_url
    970986        else:
    971987            post_url = reverse('admin:index',
    972988                               current_app=self.admin_site.name)
    class ModelAdmin(BaseModelAdmin): 
    11491165        ModelForm = self.get_form(request, obj)
    11501166        formsets = []
    11511167        inline_instances = self.get_inline_instances(request, obj)
     1168        changelist_filters = None
    11521169        if request.method == 'POST':
     1170            changelist_filters = request.POST.get('_changelist_filters')
    11531171            form = ModelForm(request.POST, request.FILES, instance=obj)
    11541172            if form.is_valid():
    11551173                form_validated = True
    class ModelAdmin(BaseModelAdmin): 
    11881206                                  queryset=inline.get_queryset(request))
    11891207                formsets.append(formset)
    11901208
     1209            referer = request.META.get('HTTP_REFERER')
     1210            if referer:
     1211                referer = urllib_parse.urlparse(referer)
     1212                changelist_url = reverse('admin:%s_%s_changelist' % (opts.app_label, opts.model_name))
     1213                if is_safe_url(url=referer.geturl(), host=request.get_host()) and referer.path.startswith(changelist_url):
     1214                    changelist_filters = referer.query
     1215
    11911216        adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj),
    11921217            self.get_prepopulated_fields(request, obj),
    11931218            self.get_readonly_fields(request, obj),
    class ModelAdmin(BaseModelAdmin): 
    12141239            'inline_admin_formsets': inline_admin_formsets,
    12151240            'errors': helpers.AdminErrorList(form, formsets),
    12161241            'app_label': opts.app_label,
     1242            'changelist_filters': changelist_filters,
    12171243        }
    12181244        context.update(extra_context or {})
    12191245        return self.render_change_form(request, context, change=True, obj=obj, form_url=form_url)
    class ModelAdmin(BaseModelAdmin): 
    14061432                                       'obj': force_text(obj_display)},
    14071433                              messages.SUCCESS)
    14081434
     1435            changelist_url = reverse('admin:%s_%s_changelist' %
     1436                                     (opts.app_label, opts.model_name),
     1437                                     current_app=self.admin_site.name)
     1438
     1439            changelist_filters = request.POST.get('_changelist_filters')
     1440            if changelist_filters:
     1441                return HttpResponseRedirect('%s?%s' % (changelist_url, changelist_filters))
     1442
    14091443            if not self.has_change_permission(request, None):
    14101444                return HttpResponseRedirect(reverse('admin:index',
    14111445                                                    current_app=self.admin_site.name))
    1412             return HttpResponseRedirect(reverse('admin:%s_%s_changelist' %
    1413                                         (opts.app_label, opts.model_name),
    1414                                         current_app=self.admin_site.name))
     1446            return HttpResponseRedirect(changelist_url)
     1447        else:
     1448            changelist_filters = request.GET.get('_changelist_filters')
     1449            if changelist_filters:
     1450                changelist_filters = unquote(changelist_filters)
    14151451
    14161452        object_name = force_text(opts.verbose_name)
    14171453
    class ModelAdmin(BaseModelAdmin): 
    14291465            "protected": protected,
    14301466            "opts": opts,
    14311467            "app_label": app_label,
     1468            "changelist_filters": changelist_filters,
    14321469        }
    14331470        context.update(extra_context or {})
    14341471
  • django/contrib/admin/templates/admin/change_form.html

    diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html
    index 4accf80..6870be0 100644
    a b  
    3838<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.model_name }}_form">{% csrf_token %}{% block form_top %}{% endblock %}
    3939<div>
    4040{% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %}
     41{% if changelist_filters %}<input type="hidden" name="_changelist_filters" value="{{ changelist_filters }}" />{% endif %}
    4142{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
    4243{% if errors %}
    4344    <p class="errornote">
  • django/contrib/admin/templates/admin/delete_confirmation.html

    diff --git a/django/contrib/admin/templates/admin/delete_confirmation.html b/django/contrib/admin/templates/admin/delete_confirmation.html
    index c1a7115..065fa14 100644
    a b  
    3636    <form action="" method="post">{% csrf_token %}
    3737    <div>
    3838    <input type="hidden" name="post" value="yes" />
     39    {% if changelist_filters %}<input type="hidden" name="_changelist_filters" value="{{ changelist_filters }}" />{% endif %}
    3940    <input type="submit" value="{% trans "Yes, I'm sure" %}" />
    4041    </div>
    4142    </form>
  • django/contrib/admin/templates/admin/submit_line.html

    diff --git a/django/contrib/admin/templates/admin/submit_line.html b/django/contrib/admin/templates/admin/submit_line.html
    index 38a97a1..6ebd155 100644
    a b  
    11{% load i18n admin_urls %}
    22<div class="submit-row">
    33{% if show_save %}<input type="submit" value="{% trans 'Save' %}" class="default" name="_save" />{% endif %}
    4 {% if show_delete_link %}<p class="deletelink-box"><a href="{% url opts|admin_urlname:'delete' original.pk|admin_urlquote %}" class="deletelink">{% trans "Delete" %}</a></p>{% endif %}
     4{% if show_delete_link %}
     5    {% url opts|admin_urlname:'delete' original.pk|admin_urlquote as delete_url%}
     6    <p class="deletelink-box">
     7        <a href="{{ delete_url }}{% if changelist_filters %}?_changelist_filters={{ changelist_filters|admin_urlquote }}{% endif %}" class="deletelink">
     8            {% trans "Delete" %}
     9        </a>
     10    </p>
     11{% endif %}
    512{% if show_save_as_new %}<input type="submit" value="{% trans 'Save as new' %}" name="_saveasnew" />{%endif%}
    613{% if show_save_and_add_another %}<input type="submit" value="{% trans 'Save and add another' %}" name="_addanother" />{% endif %}
    714{% if show_save_and_continue %}<input type="submit" value="{% trans 'Save and continue editing' %}" name="_continue" />{% endif %}
  • django/contrib/admin/templatetags/admin_modify.py

    diff --git a/django/contrib/admin/templatetags/admin_modify.py b/django/contrib/admin/templatetags/admin_modify.py
    index cecc6ed..bccf7f2 100644
    a b def submit_row(context): 
    3737                            not is_popup and (not save_as or context['add']),
    3838        'show_save_and_continue': not is_popup and context['has_change_permission'],
    3939        'is_popup': is_popup,
    40         'show_save': True
     40        'show_save': True,
    4141    }
    4242    if context.get('original') is not None:
    4343        ctx['original'] = context['original']
     44    if context.get('changelist_filters'):
     45        ctx['changelist_filters'] = context['changelist_filters']
    4446    return ctx
    4547
    4648@register.filter
  • tests/admin_views/tests.py

    diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
    index c0925e0..e853e52 100644
    a b class AdminUserMessageTest(TestCase): 
    41574157        self.assertContains(response,
    41584158                            '<li class="extra_tag info">Test tags</li>',
    41594159                            html=True)
     4160
     4161
     4162@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
     4163class AdminChangeListRedirectionTests(TestCase):
     4164    urls = "admin_views.urls"
     4165    fixtures = ['admin-views-users']
     4166
     4167    def setUp(self):
     4168        Person.objects.create(name="Chris", gender=1, alive=True, age=25)
     4169        Person.objects.create(name="Jack", gender=2, alive=False, age=47)
     4170        Person.objects.create(name="Bob", gender=1, alive=True, age=36)
     4171
     4172        self.client.login(username='super', password='secret')
     4173
     4174    def get_data(self):
     4175        return {
     4176            'name': 'Joe', 'gender': '1', 'alive': '1', 'age': '58'
     4177        }
     4178
     4179    def tearDown(self):
     4180        self.client.logout()
     4181
     4182    def get_filters_querystring(self):
     4183        return urlencode({
     4184                'alive': 1,
     4185            })
     4186
     4187    def get_filtered_changelist_url(self):
     4188        return "%s%s?%s" % ('http://testserver', reverse('admin:admin_views_person_changelist'), self.get_filters_querystring())
     4189
     4190    def test_change_redirect(self):
     4191        """
     4192        Ensure that we're correctly redirected to the filtered changelist
     4193        after an existing object is saved.
     4194        Refs #6903.
     4195        """
     4196        person = Person.objects.get(name='Chris')
     4197        change_url = reverse('admin:admin_views_person_change', args=(person.pk,))
     4198
     4199        # Simulate clicking an object from a filtered changelist
     4200        response = self.client.get(change_url, HTTP_REFERER=self.get_filtered_changelist_url())
     4201        self.assertContains(response, '_changelist_filters')
     4202        self.assertContains(response, self.get_filters_querystring())
     4203
     4204        # Save the object
     4205        data = self.get_data()
     4206        data['_save'] = 1
     4207        data['_changelist_filters'] = self.get_filters_querystring()
     4208        response = self.client.post(change_url, data)
     4209
     4210        # Check that we return to the filtered changelist
     4211        self.assertRedirects(response, self.get_filtered_changelist_url())
     4212
     4213    def test_add_redirect(self):
     4214        """
     4215        Ensure that we're correctly redirected to the non-filtered changelist
     4216        after a new object is added.
     4217        Refs #6903.
     4218        """
     4219        add_url = reverse('admin:admin_views_person_add')
     4220
     4221        response = self.client.get(add_url, HTTP_REFERER=self.get_filtered_changelist_url())
     4222        self.assertNotContains(response, '_changelist_filters')
     4223        self.assertNotContains(response, self.get_filters_querystring())
     4224
     4225        # Add a new object
     4226        data = self.get_data()
     4227        data['_save'] = 1
     4228        data['_changelist_filters'] = self.get_filters_querystring()
     4229        response = self.client.post(add_url, data)
     4230
     4231        # Check that we return to the non-filtered changelist
     4232        self.assertRedirects(response, reverse('admin:admin_views_person_changelist'))
     4233
     4234    def test_delete_redirect(self):
     4235        """
     4236        Ensure that we're correctly redirected to the filtered changelist
     4237        after an existing object is deleted.
     4238        Refs #6903.
     4239        """
     4240        person = Person.objects.get(name='Chris')
     4241        delete_url = reverse('admin:admin_views_person_delete', args=(person.pk,))
     4242
     4243        response = self.client.get(delete_url + '?_changelist_filters=%s' % self.get_filters_querystring())
     4244        self.assertContains(response, '_changelist_filters')
     4245        self.assertContains(response, self.get_filters_querystring())
     4246
     4247        # Delete the object
     4248        data = {'post': 'yes', '_changelist_filters': self.get_filters_querystring()}
     4249        response = self.client.post(delete_url, data)
     4250
     4251        # Check that we return to the filtered changelist
     4252        self.assertRedirects(response, self.get_filtered_changelist_url())
     4253
Back to Top