diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index ed41c7f..bfd0f19 100644
a
|
b
|
from django.http import Http404, HttpResponse, HttpResponseRedirect
|
12 | 12 | from django.shortcuts import get_object_or_404, render_to_response |
13 | 13 | from django.utils.functional import update_wrapper |
14 | 14 | from django.utils.html import escape |
| 15 | from django.utils.http import urlquote |
15 | 16 | from django.utils.safestring import mark_safe |
16 | 17 | from django.utils.functional import curry |
17 | 18 | from django.utils.text import capfirst, get_text_list |
… |
… |
HORIZONTAL, VERTICAL = 1, 2
|
26 | 27 | # returns the <ul> class for a given radio_admin field |
27 | 28 | get_ul_class = lambda x: 'radiolist%s' % ((x == HORIZONTAL) and ' inline' or '') |
28 | 29 | |
| 30 | # GET parameter for the URL to return to after change/add views. This lets the |
| 31 | # admin save the state of the changelist page through the change/add page. |
| 32 | RETURN_GET_PARAM = 'return_to' |
| 33 | |
29 | 34 | class IncorrectLookupParameters(Exception): |
30 | 35 | pass |
31 | 36 | |
… |
… |
class ModelAdmin(BaseModelAdmin):
|
452 | 457 | pk_value = obj._get_pk_val() |
453 | 458 | |
454 | 459 | msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj)} |
455 | | # Here, we distinguish between different save types by checking for |
| 460 | |
| 461 | # Below, we distinguish between different save types by checking for |
456 | 462 | # the presence of keys in request.POST. |
| 463 | |
| 464 | # The user clicked "save and continue editing". Redirect to admin URL |
| 465 | # for this object, possibly in popup mode if needed. |
457 | 466 | if request.POST.has_key("_continue"): |
458 | 467 | self.message_user(request, msg + ' ' + _("You may edit it again below.")) |
459 | 468 | if request.POST.has_key("_popup"): |
460 | 469 | post_url_continue += "?_popup=1" |
461 | 470 | return HttpResponseRedirect(post_url_continue % pk_value) |
462 | 471 | |
| 472 | # This was a popup and the user clicked the simple "save" button. |
| 473 | # Return a little script which populates the calling page with the |
| 474 | # saved key. |
463 | 475 | if request.POST.has_key("_popup"): |
464 | 476 | return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \ |
465 | 477 | # escape() calls force_unicode. |
466 | 478 | (escape(pk_value), escape(obj))) |
| 479 | |
| 480 | # The user clicked "save and add another", so redirect back to the bare |
| 481 | # "add" page, which will be request.path. |
467 | 482 | elif request.POST.has_key("_addanother"): |
468 | 483 | self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) |
469 | 484 | return HttpResponseRedirect(request.path) |
| 485 | |
| 486 | # Just a regular "save" click. IF we've been pased an explicit return |
| 487 | # URL in GET, go there. Otherwise, redirect to the plain changelist. |
| 488 | # If the user doesn't have changelist permission, just redirect back |
| 489 | # to the main admin index. |
470 | 490 | else: |
471 | 491 | self.message_user(request, msg) |
472 | | |
473 | | # Figure out where to redirect. If the user has change permission, |
474 | | # redirect to the change-list page for this object. Otherwise, |
475 | | # redirect to the admin index. |
476 | | if self.has_change_permission(request, None): |
| 492 | if RETURN_GET_PARAM in request.GET: |
| 493 | post_url = request.GET[RETURN_GET_PARAM] |
| 494 | elif self.has_change_permission(request, None): |
477 | 495 | post_url = '../' |
478 | 496 | else: |
479 | 497 | post_url = '../../../' |
| 498 | |
480 | 499 | return HttpResponseRedirect(post_url) |
481 | 500 | |
482 | 501 | def response_change(self, request, obj): |
… |
… |
class ModelAdmin(BaseModelAdmin):
|
487 | 506 | pk_value = obj._get_pk_val() |
488 | 507 | |
489 | 508 | msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj)} |
| 509 | |
| 510 | # Similar redirecting logic to response_add, above. |
| 511 | |
| 512 | # "Save and continue editing" |
490 | 513 | if request.POST.has_key("_continue"): |
491 | 514 | self.message_user(request, msg + ' ' + _("You may edit it again below.")) |
492 | 515 | if request.REQUEST.has_key('_popup'): |
493 | 516 | return HttpResponseRedirect(request.path + "?_popup=1") |
494 | 517 | else: |
495 | 518 | return HttpResponseRedirect(request.path) |
| 519 | |
| 520 | # "Save as a new object" |
496 | 521 | elif request.POST.has_key("_saveasnew"): |
497 | 522 | msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(opts.verbose_name), 'obj': obj} |
498 | 523 | self.message_user(request, msg) |
499 | 524 | return HttpResponseRedirect("../%s/" % pk_value) |
| 525 | |
| 526 | # "Save and add another" |
500 | 527 | elif request.POST.has_key("_addanother"): |
501 | 528 | self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) |
502 | 529 | return HttpResponseRedirect("../add/") |
| 530 | |
| 531 | # "Save" |
503 | 532 | else: |
504 | 533 | self.message_user(request, msg) |
505 | | return HttpResponseRedirect("../") |
506 | | |
| 534 | post_url = request.GET.get(RETURN_GET_PARAM, '../') |
| 535 | return HttpResponseRedirect(post_url) |
| 536 | |
507 | 537 | def add_view(self, request, form_url='', extra_context=None): |
508 | | "The 'add' admin view for this model." |
| 538 | """ |
| 539 | The 'add' admin view for this model. |
| 540 | """ |
509 | 541 | model = self.model |
510 | 542 | opts = model._meta |
511 | 543 | |
… |
… |
class ModelAdmin(BaseModelAdmin):
|
515 | 547 | ModelForm = self.get_form(request) |
516 | 548 | formsets = [] |
517 | 549 | if request.method == 'POST': |
| 550 | return_to = request.GET.get(RETURN_GET_PARAM, None) |
| 551 | |
518 | 552 | form = ModelForm(request.POST, request.FILES) |
519 | 553 | if form.is_valid(): |
520 | 554 | form_validated = True |
… |
… |
class ModelAdmin(BaseModelAdmin):
|
550 | 584 | for FormSet in self.get_formsets(request): |
551 | 585 | formset = FormSet(instance=self.model()) |
552 | 586 | formsets.append(formset) |
553 | | |
| 587 | |
| 588 | return_to = request.META.get('HTTP_REFERER', None) |
| 589 | |
| 590 | if return_to: |
| 591 | form_url = form_url + '?%s=%s' % (RETURN_GET_PARAM, urlquote(return_to)) |
| 592 | |
554 | 593 | adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields) |
555 | 594 | media = self.media + adminForm.media |
556 | 595 | |
… |
… |
class ModelAdmin(BaseModelAdmin):
|
573 | 612 | 'app_label': opts.app_label, |
574 | 613 | } |
575 | 614 | context.update(extra_context or {}) |
576 | | return self.render_change_form(request, context, add=True) |
| 615 | return self.render_change_form(request, context, form_url=form_url, add=True) |
577 | 616 | add_view = transaction.commit_on_success(add_view) |
578 | 617 | |
579 | 618 | def change_view(self, request, object_id, extra_context=None): |
… |
… |
class ModelAdmin(BaseModelAdmin):
|
601 | 640 | ModelForm = self.get_form(request, obj) |
602 | 641 | formsets = [] |
603 | 642 | if request.method == 'POST': |
| 643 | return_to = request.GET.get(RETURN_GET_PARAM, None) |
| 644 | |
604 | 645 | form = ModelForm(request.POST, request.FILES, instance=obj) |
605 | 646 | if form.is_valid(): |
606 | 647 | form_validated = True |
… |
… |
class ModelAdmin(BaseModelAdmin):
|
628 | 669 | for FormSet in self.get_formsets(request, obj): |
629 | 670 | formset = FormSet(instance=obj) |
630 | 671 | formsets.append(formset) |
631 | | |
| 672 | |
| 673 | return_to = request.META.get('HTTP_REFERER', None) |
| 674 | |
| 675 | if return_to: |
| 676 | form_url = '?%s=%s' % (RETURN_GET_PARAM, urlquote(return_to)) |
| 677 | else: |
| 678 | form_url = '' |
| 679 | |
632 | 680 | adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields) |
633 | 681 | media = self.media + adminForm.media |
634 | 682 | |
… |
… |
class ModelAdmin(BaseModelAdmin):
|
652 | 700 | 'app_label': opts.app_label, |
653 | 701 | } |
654 | 702 | context.update(extra_context or {}) |
655 | | return self.render_change_form(request, context, change=True, obj=obj) |
| 703 | return self.render_change_form(request, context, change=True, form_url=form_url, obj=obj) |
656 | 704 | change_view = transaction.commit_on_success(change_view) |
657 | 705 | |
658 | 706 | def changelist_view(self, request, extra_context=None): |