Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirecting in Admin Site

I have an app called CMS with Category and Article. Quite simple.

I overwrite app_index.html to enable ajax-based drag-n-drop ordering and to move articles from one category to another.

Now I would like to redirect after saving/deleting an article or a category to cms' app_index.html instead of the model's change_list.html. How can this be done?

Thanks

class Category(models.Model):
    order = models.IntegerField()
    title = models.CharField(max_length=100)
    text  = models.TextField()

class Article(models.Model):
    published  = models.BooleanField(default=None)
    images     = generic.GenericRelation(Photo)
    category = models.ForeignKey(Category)
    title = models.CharField(max_length=100)
    text  = models.TextField()
    order = models.IntegerField(blank = True, null = True)

Daniel's answer did half the job: Redirect after changing the articles and categories.


A not very elegant solution: Redirection in urls.py

def redirect_cms(response):
    return HttpResponseRedirect('/admin/cms/')

urlpatterns += patterns('',
    (r'^admin/cms/article/$',redirect_cms),

any other idea?

like image 541
vikingosegundo Avatar asked Oct 07 '09 15:10

vikingosegundo


3 Answers

In your admin subclass, override the response_change and/or the response_add methods. These are called after the admin form is saved ,for existing and new instances respectively, and are responsible for returning the HttpResponseRedirect that currently takes you to the change_list page.

Take a look at the original code in django.contrib.admin.options to see what you need to do.

Edit: There are two ways a deletion can take place: as a result of an action on the change_list page, in which case you can use the response_action method; or as a result of a deletion on the change form, in which case unfortunately there is no equivalent method. One way of dealing with this might be to override the change_form.html template for the app, and remove the deletion link, so that the only way to delete is via the changelist. Not ideal by any means.

like image 60
Daniel Roseman Avatar answered Oct 05 '22 12:10

Daniel Roseman


The question is already answered, but the problem of redirect after delete is not covered. Maybe the following solution will be helpful for somebody. Django's ModelAdmin class has got delete_view member function. It does two things:

  1. If POST is not defined, shows Deletion confirmation page. If you confirm and click Delete, it generates a POST request.
  2. As POST is now defined, the view deletes the requested items and returns an HttpResponseRedirect to changelist (or admin index, if the user doesn't have a permission to change).

So, let's override this as follows.

from django.http import HttpResponseRedirect

class MyAdmin(admin.ModelAdmin):
    def delete_view(self, request, object_id, extra_context=None):
        """Redirect to website index page on delete."""

        response = super(MyAdmin, self).delete_view(request, object_id, extra_context)

        # Use our own redirect
        if isinstance(response, HttpResponseRedirect):
            return HttpResponseRedirect('/') # Any URL here

        return response

It seems working for me under Django 1.6.

like image 41
Anatoly Scherbakov Avatar answered Oct 05 '22 12:10

Anatoly Scherbakov


As of Django 1.7, there is a response_delete method which you can override on the admin object. See here

class MyAdmin(admin.ModelAdmin):

    def response_delete(self, request, obj_display):
        return HttpResponseRedirect("my_url")
like image 24
Patrick Avatar answered Oct 05 '22 11:10

Patrick