Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django admin "save and view on site" button

The Django admin site is brilliant, and we use it a lot at my work. My question is this - how do I add an additional button at the bottom, along side the 'save', 'save and continue editing' etc buttons, that saves the model and then redirects to the 'view on site' button that is available at the top right of the form for models that have that defined?

Thanks in advance!

like image 1000
Ben Avatar asked Dec 21 '11 20:12

Ben


2 Answers

Besides adding button in change_form template, you would want to override response_change method of ModelAdmin (and response_add).

Something like this should work:

def response_change(self, request, obj):
  res = super(MyModelAdmin, self).response_change(request, obj)
  if "_preview" in request.POST:
    return HttpResponseRedirect('preview-url-here')
  else:
    return res
like image 151
bmihelac Avatar answered Nov 11 '22 00:11

bmihelac


To do this but also have the choice to show/hide it for certain model forms, here is what I did:

1. First override the submit_line.html template by creating a custom one under the main templates folder: my_project/templates/admin/submit_line.html, copy the content from the original one and add the custom button to submit-row block (it won't be displayed by default since it's set to False):

# submit_line.html

{% load i18n admin_urls %}
<div class="submit-row">
{% block submit-row %}
{% if show_save %}<input type="submit" value="{% trans 'Save' %}" class="default" name="_save">{% endif %}
...
...
...
{% if show_save_and_preview|default:False %}<input type="submit" value="{% trans 'Save and preview' %}" name="_preview">{% endif %}
{% endblock %}
</div>


2. Next, to simply show it for certain models, just override your ModelAdmin methods:

changeform_view: to display the button on the template.

response_change: to set where it will redirect to after saving.

# admin.py

class MyModelAdmin(admin.ModelAdmin):
    # ..
    # ..

    def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
        extra_context = extra_context or {}
        extra_context['show_save_and_preview'] = True
        return super(MyModelAdmin, self).changeform_view(request, object_id, extra_context=extra_context)

    def response_change(self, request, obj):
        res = super(MyModelAdmin, self).response_change(request, obj)
        if "_preview" in request.POST:
            # used object's custom method "get_url()":
            return HttpResponseRedirect(obj.get_url())
        else:
            return res

Now it will be displayed for this particular form, to do the same for other models, just override the two methods above.

like image 26
Badjio Avatar answered Nov 10 '22 23:11

Badjio