mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #19505 -- A more flexible implementation for customizable admin redirect urls.
Work by Julien Phalip.
Refs #8001, #18310, #19505. See also 0b908b92a2.
			
			
This commit is contained in:
		
				
					committed by
					
						 Ramiro Morales
						Ramiro Morales
					
				
			
			
				
	
			
			
			
						parent
						
							4a71b84266
						
					
				
				
					commit
					35d1cd0b28
				
			| @@ -9,7 +9,7 @@ from django.forms.models import (modelform_factory, modelformset_factory, | ||||
|     inlineformset_factory, BaseInlineFormSet) | ||||
| from django.contrib.contenttypes.models import ContentType | ||||
| from django.contrib.admin import widgets, helpers | ||||
| from django.contrib.admin.util import quote, unquote, flatten_fieldsets, get_deleted_objects, model_format_dict | ||||
| from django.contrib.admin.util import unquote, flatten_fieldsets, get_deleted_objects, model_format_dict | ||||
| from django.contrib.admin.templatetags.admin_static import static | ||||
| from django.contrib import messages | ||||
| from django.views.decorators.csrf import csrf_protect | ||||
| @@ -38,6 +38,7 @@ HORIZONTAL, VERTICAL = 1, 2 | ||||
| # returns the <ul> class for a given radio_admin field | ||||
| get_ul_class = lambda x: 'radiolist%s' % ((x == HORIZONTAL) and ' inline' or '') | ||||
|  | ||||
|  | ||||
| class IncorrectLookupParameters(Exception): | ||||
|     pass | ||||
|  | ||||
| @@ -62,6 +63,7 @@ FORMFIELD_FOR_DBFIELD_DEFAULTS = { | ||||
|  | ||||
| csrf_protect_m = method_decorator(csrf_protect) | ||||
|  | ||||
|  | ||||
| class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): | ||||
|     """Functionality common to both ModelAdmin and InlineAdmin.""" | ||||
|  | ||||
| @@ -150,7 +152,7 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): | ||||
|                 }) | ||||
|             if 'choices' not in kwargs: | ||||
|                 kwargs['choices'] = db_field.get_choices( | ||||
|                     include_blank = db_field.blank, | ||||
|                     include_blank=db_field.blank, | ||||
|                     blank_choice=[('', _('None'))] | ||||
|                 ) | ||||
|         return db_field.formfield(**kwargs) | ||||
| @@ -787,49 +789,37 @@ class ModelAdmin(BaseModelAdmin): | ||||
|             "admin/change_form.html" | ||||
|         ], context, current_app=self.admin_site.name) | ||||
|  | ||||
|     def response_add(self, request, obj, post_url_continue='../%s/', | ||||
|                      continue_editing_url=None, add_another_url=None, | ||||
|                      hasperm_url=None, noperm_url=None): | ||||
|     def response_add(self, request, obj, post_url_continue=None): | ||||
|         """ | ||||
|         Determines the HttpResponse for the add_view stage. | ||||
|  | ||||
|         :param request: HttpRequest instance. | ||||
|         :param obj: Object just added. | ||||
|         :param post_url_continue: Deprecated/undocumented. | ||||
|         :param continue_editing_url: URL where user will be redirected after | ||||
|                                      pressing 'Save and continue editing'. | ||||
|         :param add_another_url: URL where user will be redirected after | ||||
|                                 pressing 'Save and add another'. | ||||
|         :param hasperm_url: URL to redirect after a successful object creation | ||||
|                             when the user has change permissions. | ||||
|         :param noperm_url: URL to redirect after a successful object creation | ||||
|                            when the user has no change permissions. | ||||
|         """ | ||||
|         if post_url_continue != '../%s/': | ||||
|             warnings.warn("The undocumented 'post_url_continue' argument to " | ||||
|                           "ModelAdmin.response_add() is deprecated, use the new " | ||||
|                           "*_url arguments instead.", DeprecationWarning, | ||||
|                           stacklevel=2) | ||||
|         opts = obj._meta | ||||
|         pk_value = obj.pk | ||||
|         app_label = opts.app_label | ||||
|         model_name = opts.module_name | ||||
|         site_name = self.admin_site.name | ||||
|         pk_value = obj._get_pk_val() | ||||
|  | ||||
|         msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)} | ||||
|  | ||||
|         # Here, we distinguish between different save types by checking for | ||||
|         # the presence of keys in request.POST. | ||||
|         if "_continue" in request.POST: | ||||
|             msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict | ||||
|             self.message_user(request, msg) | ||||
|             if continue_editing_url is None: | ||||
|                 continue_editing_url = 'admin:%s_%s_change' % (app_label, model_name) | ||||
|             url = reverse(continue_editing_url, args=(quote(pk_value),), | ||||
|                           current_app=site_name) | ||||
|             if post_url_continue is None: | ||||
|                 post_url_continue = reverse('admin:%s_%s_change' % | ||||
|                                             (opts.app_label, opts.module_name), | ||||
|                                             args=(pk_value,), | ||||
|                                             current_app=self.admin_site.name) | ||||
|             else: | ||||
|                 try: | ||||
|                     post_url_continue = post_url_continue % pk_value | ||||
|                     warnings.warn( | ||||
|                         "The use of string formats for post_url_continue " | ||||
|                         "in ModelAdmin.response_add() is deprecated. Provide " | ||||
|                         "a pre-formatted url instead.", | ||||
|                         DeprecationWarning, stacklevel=2) | ||||
|                 except TypeError: | ||||
|                     pass | ||||
|             if "_popup" in request.POST: | ||||
|                 url += "?_popup=1" | ||||
|             return HttpResponseRedirect(url) | ||||
|                 post_url_continue += "?_popup=1" | ||||
|             return HttpResponseRedirect(post_url_continue) | ||||
|  | ||||
|         if "_popup" in request.POST: | ||||
|             return HttpResponse( | ||||
| @@ -840,102 +830,61 @@ class ModelAdmin(BaseModelAdmin): | ||||
|         elif "_addanother" in request.POST: | ||||
|             msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict | ||||
|             self.message_user(request, msg) | ||||
|             if add_another_url is None: | ||||
|                 add_another_url = 'admin:%s_%s_add' % (app_label, model_name) | ||||
|             url = reverse(add_another_url, current_app=site_name) | ||||
|             return HttpResponseRedirect(url) | ||||
|             return HttpResponseRedirect(request.path) | ||||
|         else: | ||||
|             msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict | ||||
|             self.message_user(request, msg) | ||||
|             return self.response_post_save(request, obj) | ||||
|  | ||||
|             # Figure out where to redirect. If the user has change permission, | ||||
|             # redirect to the change-list page for this object. Otherwise, | ||||
|             # redirect to the admin index. | ||||
|             if self.has_change_permission(request, None): | ||||
|                 if hasperm_url is None: | ||||
|                     hasperm_url = 'admin:%s_%s_changelist' % (app_label, model_name) | ||||
|                 url = reverse(hasperm_url, current_app=site_name) | ||||
|             else: | ||||
|                 if noperm_url is None: | ||||
|                     noperm_url = 'admin:index' | ||||
|                 url = reverse(noperm_url, current_app=site_name) | ||||
|             return HttpResponseRedirect(url) | ||||
|  | ||||
|     def response_change(self, request, obj, continue_editing_url=None, | ||||
|                         save_as_new_url=None, add_another_url=None, | ||||
|                         hasperm_url=None, noperm_url=None): | ||||
|     def response_change(self, request, obj): | ||||
|         """ | ||||
|         Determines the HttpResponse for the change_view stage. | ||||
|  | ||||
|         :param request: HttpRequest instance. | ||||
|         :param obj: Object just modified. | ||||
|         :param continue_editing_url: URL where user will be redirected after | ||||
|                                      pressing 'Save and continue editing'. | ||||
|         :param save_as_new_url: URL where user will be redirected after pressing | ||||
|                                 'Save as new' (when applicable). | ||||
|         :param add_another_url: URL where user will be redirected after pressing | ||||
|                                 'Save and add another'. | ||||
|         :param hasperm_url: URL to redirect after a successful object edition when | ||||
|                             the user has change permissions. | ||||
|         :param noperm_url: URL to redirect after a successful object edition when | ||||
|                            the user has no change permissions. | ||||
|         """ | ||||
|         opts = obj._meta | ||||
|         opts = self.model._meta | ||||
|  | ||||
|         app_label = opts.app_label | ||||
|         model_name = opts.module_name | ||||
|         site_name = self.admin_site.name | ||||
|         verbose_name = opts.verbose_name | ||||
|         # Handle proxy models automatically created by .only() or .defer(). | ||||
|         # Refs #14529 | ||||
|         if obj._deferred: | ||||
|             opts_ = opts.proxy_for_model._meta | ||||
|             verbose_name = opts_.verbose_name | ||||
|             model_name = opts_.module_name | ||||
|  | ||||
|         msg_dict = {'name': force_text(verbose_name), 'obj': force_text(obj)} | ||||
|         pk_value = obj._get_pk_val() | ||||
|  | ||||
|         msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)} | ||||
|         if "_continue" in request.POST: | ||||
|             msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict | ||||
|             self.message_user(request, msg) | ||||
|             if continue_editing_url is None: | ||||
|                 continue_editing_url = 'admin:%s_%s_change' % (app_label, model_name) | ||||
|             url = reverse(continue_editing_url, args=(quote(obj.pk),), | ||||
|                           current_app=site_name) | ||||
|             if "_popup" in request.POST: | ||||
|                 url += "?_popup=1" | ||||
|             return HttpResponseRedirect(url) | ||||
|             if "_popup" in request.REQUEST: | ||||
|                 return HttpResponseRedirect(request.path + "?_popup=1") | ||||
|             else: | ||||
|                 return HttpResponseRedirect(request.path) | ||||
|         elif "_saveasnew" in request.POST: | ||||
|             msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict | ||||
|             self.message_user(request, msg) | ||||
|             if save_as_new_url is None: | ||||
|                 save_as_new_url = 'admin:%s_%s_change' % (app_label, model_name) | ||||
|             url = reverse(save_as_new_url, args=(quote(obj.pk),), | ||||
|                           current_app=site_name) | ||||
|             return HttpResponseRedirect(url) | ||||
|             return HttpResponseRedirect(reverse('admin:%s_%s_change' % | ||||
|                                         (opts.app_label, opts.module_name), | ||||
|                                         args=(pk_value,), | ||||
|                                         current_app=self.admin_site.name)) | ||||
|         elif "_addanother" in request.POST: | ||||
|             msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict | ||||
|             self.message_user(request, msg) | ||||
|             if add_another_url is None: | ||||
|                 add_another_url = 'admin:%s_%s_add' % (app_label, model_name) | ||||
|             url = reverse(add_another_url, current_app=site_name) | ||||
|             return HttpResponseRedirect(url) | ||||
|             return HttpResponseRedirect(reverse('admin:%s_%s_add' % | ||||
|                                         (opts.app_label, opts.module_name), | ||||
|                                         current_app=self.admin_site.name)) | ||||
|         else: | ||||
|             msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict | ||||
|             self.message_user(request, msg) | ||||
|             # Figure out where to redirect. If the user has change permission, | ||||
|             # redirect to the change-list page for this object. Otherwise, | ||||
|             # redirect to the admin index. | ||||
|             if self.has_change_permission(request, None): | ||||
|                 if hasperm_url is None: | ||||
|                     hasperm_url = 'admin:%s_%s_changelist' % (app_label, | ||||
|                                                               model_name) | ||||
|                 url = reverse(hasperm_url, current_app=site_name) | ||||
|             else: | ||||
|                 if noperm_url is None: | ||||
|                     noperm_url = 'admin:index' | ||||
|                 url = reverse(noperm_url, current_app=site_name) | ||||
|             return HttpResponseRedirect(url) | ||||
|             return self.response_post_save(request, obj) | ||||
|  | ||||
|     def response_post_save(self, request, obj): | ||||
|         """ | ||||
|         Figure out where to redirect after the 'Save' button has been pressed. | ||||
|         If the user has change permission, redirect to the change-list page for | ||||
|         this object. Otherwise, redirect to the admin index. | ||||
|         """ | ||||
|         opts = self.model._meta | ||||
|         if self.has_change_permission(request, None): | ||||
|             post_url = reverse('admin:%s_%s_changelist' % | ||||
|                                (opts.app_label, opts.module_name), | ||||
|                                current_app=self.admin_site.name) | ||||
|         else: | ||||
|             post_url = reverse('admin:index', | ||||
|                                current_app=self.admin_site.name) | ||||
|         return HttpResponseRedirect(post_url) | ||||
|  | ||||
|     def response_action(self, request, queryset): | ||||
|         """ | ||||
|   | ||||
| @@ -153,7 +153,7 @@ class UserAdmin(admin.ModelAdmin): | ||||
|             'admin/auth/user/change_password.html', | ||||
|             context, current_app=self.admin_site.name) | ||||
|  | ||||
|     def response_add(self, request, obj, **kwargs): | ||||
|     def response_add(self, request, obj, post_url_continue=None): | ||||
|         """ | ||||
|         Determines the HttpResponse for the add_view stage. It mostly defers to | ||||
|         its superclass implementation but is customized because the User model | ||||
| @@ -166,7 +166,8 @@ class UserAdmin(admin.ModelAdmin): | ||||
|         # * We are adding a user in a popup | ||||
|         if '_addanother' not in request.POST and '_popup' not in request.POST: | ||||
|             request.POST['_continue'] = 1 | ||||
|         return super(UserAdmin, self).response_add(request, obj, **kwargs) | ||||
|         return super(UserAdmin, self).response_add(request, obj, | ||||
|                                                    post_url_continue) | ||||
|  | ||||
| admin.site.register(Group, GroupAdmin) | ||||
| admin.site.register(User, UserAdmin) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user