5

In my django project I create a link to the admin interface so that users can edit the object:

<a href="{% url admin:mode_change object.id %}">modify object</a>

this works fine, but after the user finished editing the object in the admin interface, I would love to automatically bring the user back to the original URL (or some other URL). Currently, after the user modified the object, she / he ends up in the admin interface looking at all model entries.

Is there a way to provide a return url to an admin link?

memyself
  • 11,907
  • 14
  • 61
  • 102

2 Answers2

10

this seems to work:

admin.py:
class ModelAdmin(admin.ModelAdmin):
    form = ModelForm

    def response_change(self, request, obj):
        res = super(ModelAdmin, self).response_change(request, obj)
        if "next" in request.GET:
            return HttpResponseRedirect(request.GET['next'])
        else:
            return res

and in the template (where currentUrl is a variable generated in the view):

<a href="{% url admin:mode_change object.id %}?next={{ currentUrl }}">modify object</a>
memyself
  • 11,907
  • 14
  • 61
  • 102
  • 3
    This leaves you open to an Open Redirect attack. https://www.owasp.org/index.php/Open_redirect . Use django.utils.http.is_safe_url. Also, in the template, you could do {{ request.get_full_path|urlencode }} instead of {{ currentUrl }}. Also, this does the redirect even if the save wasn't successful – spookylukey Nov 19 '13 at 12:25
  • @spookylukey do you have a better alternative? – Private Nov 28 '17 at 15:45
  • How do you preserve the successful save message that would normally be inserted into the request, but isn't? – Cloud Artisans May 15 '20 at 03:10
5

The method "response_post_save_change" would be better for this question, because it is called only after successful save. On Django 3.1 this worked for me:

def response_post_save_change(self, request, obj):
    res = super().response_post_save_change(request, obj)
    if "next" in request.GET:
        return HttpResponseRedirect(reverse(...))
    else:
        return res
limugob
  • 51
  • 1
  • 1