lambdamusic
2/7/2013 - 9:26 PM

Django: Override the change_view in the admin

Django: Override the change_view in the admin

# in your models.py, or admin.py

from django.http import HttpResponseRedirect
from django.utils.encoding import force_unicode
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse

	class Admin(ModelAdmin):


                # ps: this will catch the change action only; for add actions override the response_add method in a similar way
		def response_change(self, request, obj):
			""" custom method that cacthes a new 'save and edit next' action 
				Remember that the type of 'obj' is the current model instance, so we can use it dynamically!
			"""
			opts = obj._meta
			verbose_name = opts.verbose_name
			module_name = opts.module_name
			pk_value = obj._get_pk_val()

			if "_addnextid" in request.POST:
				msg = _("""The %(name)s "%(obj)s" was added successfully. Now you're editing the following %(name)s, according to its ID number.""") % {'name': force_unicode(verbose_name), 'obj': obj}
				self.message_user(request, msg)

				try:
					next_obj = [x.id for x in obj.__class__.objects.filter(id__gt=pk_value).order_by('id')][0]
				except:
					print "ERROR"
					next_obj = pk_value
				return HttpResponseRedirect(reverse('admin:%s_%s_change' % 
													(opts.app_label, module_name),
													 args=(next_obj,),
													current_app=self.admin_site.name))
			else:
				return super(obj.Admin, self).response_change(request, obj)



# OPTION 1 : then override submit_line.html  => it'll make the new button appear on all change forms


{% load i18n %}
<div class="submit-row" {% if is_popup %}style="overflow: auto;"{% endif %}>
{% if show_save %}<input type="submit" value="{% trans 'Save' %}" class="default" name="_save" {{ onclick_attrib }}/>{% endif %}
{% if show_delete_link %}<p class="deletelink-box"><a href="delete/" class="deletelink">{% trans "Delete" %}</a></p>{% endif %}
{% if show_save_as_new %}<input type="submit" value="{% trans 'Save as new' %}" name="_saveasnew" {{ onclick_attrib }}/>{%endif%}

{# ADD ON: EDIT NEXT ID ITEM LINK: we don't show it if a new item is being added by using the 'delete' flag #}

{% if show_delete_link %}<input type="submit" value="{% trans 'Save and edit next item (by ID)' %}" name="_addnextid" {{ onclick_attrib }} />{% endif %}

{% if show_save_and_add_another %}<input type="submit" value="{% trans 'Save and add another' %}" name="_addanother" {{ onclick_attrib }} />{% endif %}
{% if show_save_and_continue %}<input type="submit" value="{% trans 'Save and continue editing' %}" name="_continue" {{ onclick_attrib }}/>{% endif %}
</div>







# OPTION 2 : add the new button via js ==> you can more easily decide which model template the button should appear on
# http://stackoverflow.com/questions/3874231/adding-an-extra-button-to-one-object-in-django-admin


# static/js/admin_addon.js

function update_document() {	
	// for the Source template:
	$('input[name="_addanother"]').before('<input type="submit" name="_addnextid" value="Save and edit next item (by ID)"/>');
	
	
}

// give time to jquery to load..
setTimeout("update_document();", 1000);



# models.py

class MyModelAdmin(admin.ModelAdmin):
    class Media:
        js = ("js/admin_addon.js",)