Return to Snippet

Revision: 55097
at January 31, 2012 05:50 by magicrebirth


Updated Code
# 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",)

Revision: 55096
at January 31, 2012 05:13 by magicrebirth


Updated Code
# 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):

		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",)

Revision: 55095
at January 26, 2012 23:43 by magicrebirth


Updated Code
# in your models.py, or admin.py


	class Admin(ModelAdmin):

		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",)

Revision: 55094
at January 26, 2012 23:41 by magicrebirth


Updated Code
# in your models.py, or admin.py


	class Admin(ModelAdmin):

		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


# 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",)

Revision: 55093
at January 26, 2012 04:50 by magicrebirth


Updated Code
# in your models.py, or admin.py


	class Admin(ModelAdmin):

		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)



# then override submit_line.html


{% 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>

Revision: 55092
at January 26, 2012 04:35 by magicrebirth


Initial Code
# in your models.py, or admin.py


	class Admin(ModelAdmin):

		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)

Initial URL
https://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py#L445

Initial Description
Adding another button with name "addnextid" would trigger our custom action, that redirects the user to the changeform screen for the next available item (by ID).

Then you can override admin/submit_line.html. Copy the version in contrib.admin.templates into your project. Mine is myproject/templates/admin/submit_line.html, but you could use /myproject/myapp/templates/admin/submit_line.html.

Next, edit the copy and add the code for showing the 'Save and edit next item (by ID)' link, which is caught via the "_addnextid" name. 

p.s.
The submit_line.html template is called in change_form.html via the {% submit_row %} tag.

Initial Title
Override the change_view in the admin

Initial Tags


Initial Language
Django