On 1/11/06, Joseph Kocherhans <[EMAIL PROTECTED]> wrote: > I hate to request more changes to magic-removal... but that's where > this should happen. Maybe it should wait until after it's been merged > though. > > Currently the redirects after add_stage and change_stage in the admin > system are hardcoded. One of the most frequent requests I get in my > projects is to allow people to go to some other related object after > they save, not back to the list of objects. The redirect should be > customizable. Here's how I propose it should be done. > > Add a template block {% block submitrow %} around the submit_row in > the admin/change_form.html. This would allow people to override the > save buttons.
This just occured to me today. I think it's flexible enough without being too complicated. def continue(request, new_object, msg): "The save and continue action for the admin system." pk_value = new_object._get_pk_val() request.user.add_message(msg + ' ' + _("You may edit it again below.")) if request.POST.has_key("_popup"): post_url_continue += "?_popup=1" return HttpResponseRedirect(post_url_continue % pk_value) default_add_options = ( ('Save and Continue Editing', '_continue', continue), ('Save and Add Another', '_addanother', add_another), ('Save', '_save', save), ) class Article(models.Model): title = models.CharField(maxlength=100) Admin: # use the defaults, but nix the first option # the default options should be easy to import so people can modify them add_options = default_add_options[1:] # use a totally custom set of options change_options = ( ('Save and Continue Editing', '_continue', continue), ('Save', '_save', save), ('Save and Add Another', '_addanother', add_another), ) add_options and change_options are tuples of tuples. Each (VERBOSE_NAME, POST_VAR_NAME, CALLABLE) tuple corresponds to a button/action. Now, when there are no validation errors, the admin does something like this: new_object = manipulator.save(new_data) # admin log stuff msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object} for save_option in opts.change_options: if request.POST.has_key(save_option[1]): return save_option[2](request, new_object, msg) Obviously, the first matching one gets called even if more are present in the post data. This might trip users up, but I think checking for more than one in the post data is overkill. Maybe the model validator should check though *shrug* There are a few different options for deciding which is the default. The options should be displayed in order, so. 1. The last option could implicitly be the default. 2. Add one more item, 'default', at the the end of the default options. (yuck!) 3. Another couple of Admin attributes set to the HTTP var name: default_add_option = '_continue' default_change_option = '_addanother' I like a combination of 1 and 3 the best. Implicitly use the last tuple as the default (so there's ALWAYS a default) and override that default with default_add/change_option. Thoughts? Also, the post_url='../', post_url_continue='../%s/' args should be removed from add_stage, or added to change_stage. My vote is for removing them, or maybe we could pass in a tuple of options exactly like the new Admin attributes instead. If custom options get passed in, use them instead of the ones from the model, or maybe try to merge them with the passed ones taking precedence. As far as I can see, the form_url='' argument for add_stage and render_change_form aren't used correctly either. (the add_stage's form_url arg never gets passed in to render_change_form) Are these still needed? Joseph