Ticket #6903: 6903.4.diff
File 6903.4.diff, 13.0 KB (added by , 11 years ago) |
---|
-
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 14 14 from django.contrib.admin import validation 15 15 from django.contrib.admin.templatetags.admin_static import static 16 16 from django.contrib import messages 17 from django.utils.http import is_safe_url 17 18 from django.views.decorators.csrf import csrf_protect 18 19 from django.core.exceptions import PermissionDenied, ValidationError, FieldError 19 20 from django.core.paginator import Paginator … … from django.utils.translation import ugettext as _ 38 39 from django.utils.translation import ungettext 39 40 from django.utils.encoding import force_text 40 41 42 try: 43 from urllib import parse as urllib_parse 44 except ImportError: # Python 2 45 import urllib as urllib_parse 46 import urlparse 47 urllib_parse.urlparse = urlparse.urlparse 48 49 41 50 HORIZONTAL, VERTICAL = 1, 2 42 51 # returns the <ul> class for a given radio_admin field 43 52 get_ul_class = lambda x: 'radiolist%s' % (' inline' if x == HORIZONTAL else '') … … class ModelAdmin(BaseModelAdmin): 963 972 when editing an existing object. 964 973 """ 965 974 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 966 984 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 970 986 else: 971 987 post_url = reverse('admin:index', 972 988 current_app=self.admin_site.name) … … class ModelAdmin(BaseModelAdmin): 1149 1165 ModelForm = self.get_form(request, obj) 1150 1166 formsets = [] 1151 1167 inline_instances = self.get_inline_instances(request, obj) 1168 changelist_filters = None 1152 1169 if request.method == 'POST': 1170 changelist_filters = request.POST.get('_changelist_filters') 1153 1171 form = ModelForm(request.POST, request.FILES, instance=obj) 1154 1172 if form.is_valid(): 1155 1173 form_validated = True … … class ModelAdmin(BaseModelAdmin): 1188 1206 queryset=inline.get_queryset(request)) 1189 1207 formsets.append(formset) 1190 1208 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 1191 1216 adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), 1192 1217 self.get_prepopulated_fields(request, obj), 1193 1218 self.get_readonly_fields(request, obj), … … class ModelAdmin(BaseModelAdmin): 1214 1239 'inline_admin_formsets': inline_admin_formsets, 1215 1240 'errors': helpers.AdminErrorList(form, formsets), 1216 1241 'app_label': opts.app_label, 1242 'changelist_filters': changelist_filters, 1217 1243 } 1218 1244 context.update(extra_context or {}) 1219 1245 return self.render_change_form(request, context, change=True, obj=obj, form_url=form_url) … … class ModelAdmin(BaseModelAdmin): 1406 1432 'obj': force_text(obj_display)}, 1407 1433 messages.SUCCESS) 1408 1434 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 1409 1443 if not self.has_change_permission(request, None): 1410 1444 return HttpResponseRedirect(reverse('admin:index', 1411 1445 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) 1415 1451 1416 1452 object_name = force_text(opts.verbose_name) 1417 1453 … … class ModelAdmin(BaseModelAdmin): 1429 1465 "protected": protected, 1430 1466 "opts": opts, 1431 1467 "app_label": app_label, 1468 "changelist_filters": changelist_filters, 1432 1469 } 1433 1470 context.update(extra_context or {}) 1434 1471 -
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 38 38 <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 %} 39 39 <div> 40 40 {% 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 %} 41 42 {% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %} 42 43 {% if errors %} 43 44 <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 36 36 <form action="" method="post">{% csrf_token %} 37 37 <div> 38 38 <input type="hidden" name="post" value="yes" /> 39 {% if changelist_filters %}<input type="hidden" name="_changelist_filters" value="{{ changelist_filters }}" />{% endif %} 39 40 <input type="submit" value="{% trans "Yes, I'm sure" %}" /> 40 41 </div> 41 42 </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 1 1 {% load i18n admin_urls %} 2 2 <div class="submit-row"> 3 3 {% 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 %} 5 12 {% if show_save_as_new %}<input type="submit" value="{% trans 'Save as new' %}" name="_saveasnew" />{%endif%} 6 13 {% if show_save_and_add_another %}<input type="submit" value="{% trans 'Save and add another' %}" name="_addanother" />{% endif %} 7 14 {% 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): 37 37 not is_popup and (not save_as or context['add']), 38 38 'show_save_and_continue': not is_popup and context['has_change_permission'], 39 39 'is_popup': is_popup, 40 'show_save': True 40 'show_save': True, 41 41 } 42 42 if context.get('original') is not None: 43 43 ctx['original'] = context['original'] 44 if context.get('changelist_filters'): 45 ctx['changelist_filters'] = context['changelist_filters'] 44 46 return ctx 45 47 46 48 @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): 4157 4157 self.assertContains(response, 4158 4158 '<li class="extra_tag info">Test tags</li>', 4159 4159 html=True) 4160 4161 4162 @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',)) 4163 class 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