简体   繁体   English

Django 管理员“保存并在现场查看”按钮

[英]Django admin "save and view on site" button

The Django admin site is brilliant, and we use it a lot at my work. Django 管理站点非常棒,我们在工作中经常使用它。 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?我的问题是 - 我如何在底部添加一个额外的按钮,旁边是“保存”、“保存并继续编辑”等按钮,保存 model,然后重定向到可用的“现场查看”按钮在已定义模型的表格右上角?

Thanks in advance!提前致谢!

Besides adding button in change_form template, you would want to override response_change method of ModelAdmin (and response_add ). 除了在change_form模板中添加按钮外,您还希望覆盖ModelAdmin(和response_add )的response_change方法。

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

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): 1.首先通过在主模板文件夹下创建自定义模板来覆盖submit_line.html模板: my_project/templates/admin/submit_line.html ,复制原始my_project/templates/admin/submit_line.html的内容并将自定义按钮添加到submit-row块(它赢了默认显示,因为它设置为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: 2.接下来,只需为某些模型显示它,只需覆盖ModelAdmin方法:

changeform_view : to display the button on the template. changeform_view :显示模板上的按钮。

response_change : to set where it will redirect to after saving. response_change :设置保存后重定向到的位置。

# 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. 现在它将显示为此特定表单,对其他模型执行相同操作,只需覆盖上面的两个方法。

You can add a custom button at the bottom of "Add" form and "Change" form for a specifc admin.您可以在特定管理员的“添加”表单和“更改”表单的底部添加自定义按钮。

First, in the root django project directory , create "templates/admin/custom_change_form.html" as shown below:首先,在django 项目根目录下,创建“templates/admin/custom_change_form.html” ,如下图:

在此处输入图像描述

Next, under "django" library , there is "change_form.html" which is "django/contrib/admin/templates/admin/change_form.html" so copy & paste all the code of "change_form.html" to "custom_change_form.html" as shown below:接下来,在“django”库下,有“change_form.html” ,即“django/contrib/admin/templates/admin/change_form.html” ,因此将“change_form.html”的所有代码复制并粘贴到“custom_change_form.html” "如下图:

# "templates/admin/custom_change_form.html"

{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}

{% block extrahead %}{{ block.super }}
<script src="{% url 'admin:jsi18n' %}"></script>
{{ media }}
{% endblock %}

... Much more code below

Next, there is the code in line 64 as shown below:接下来是第 64 行的代码,如下所示:

# "templates/admin/custom_change_form.html"

{% block submit_buttons_bottom %}{% submit_row %}{% endblock %} # Line 64

Then, add the code below between "{% submit_row %}" and "{% endblock %}" :然后,在"{% submit_row %}""{% endblock %}"之间添加以下代码:

{% if custom_button %}
<div class="submit-row">
    <input type="submit" value="{% translate 'Custom button' %}" name="_custom_button">
</div>
{% endif %}

So, this is the full code as shown below:因此,这是完整的代码,如下所示:

# "templates/admin/custom_change_form.html"

{% block submit_buttons_bottom %} # Line 64
{% submit_row %}
{% if custom_button %}
<div class="submit-row">
    <input type="submit" value="{% translate 'Custom button' %}" name="_custom_button">
</div>
{% endif %}
{% endblock %}

Next, this is the settings for templates in "settings.py" :接下来,这是“settings.py”中模板的设置:

# "settings.py"

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Then, add "os.path.join(BASE_DIR, 'templates')" to "DIRS" as shown below:然后,将“os.path.join(BASE_DIR, 'templates')”添加到“DIRS” ,如下所示:

# "settings.py"

import os # Here

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')], # Here
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Now, this is "Person" model as shown below:现在,这是“人”model ,如下所示:

# "models.py"

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

Then, this is "Person" admin as shown below:然后,这是“人”管理员,如下所示:

# "admin.py"

from django.contrib import admin
from .models import Person

@admin.register(Person) # Here
class PersonAdmin(admin.ModelAdmin):
    pass

So next, for "Person" admin , set "admin/custom_change_form.html" to "change_form_template" , set "True" to "extra_context['custom_button']" in "changeform_view()" and set "response_add()" and "response_change()" to define the action after pressing "Custom button" in "Add" form and "Change" form respectively as shown below:接下来,对于“Person” admin ,将“admin/custom_change_form.html”设置为“change_form_template” ,在“changeform_view ()”中将“True”设置为“extra_context['custom_button']” ,并设置“response_add()”“ response_change()”分别定义在“添加”“更改”表单中按下“自定义按钮”后的动作,如下图所示:

# "admin.py"

from django.contrib import admin
from .models import Person

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    change_form_template = "admin/custom_change_form.html" # Here
    
    def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
        extra_context = extra_context or {}
        
        extra_context['custom_button'] = True # Here
        
        return super().changeform_view(request, object_id, form_url, extra_context)

    def response_add(self, request, obj, post_url_continue=None): # Here

        if "_custom_button" in request.POST:
            # Do something
            return super().response_add(request, obj, post_url_continue)
        else:
            # Do something
            return super().response_add(request, obj, post_url_continue)

    def response_change(self, request, obj): # Here
        
        if "_custom_button" in request.POST:
            # Do something
            return super().response_change(request, obj)
        else:
            # Do something
            return super().response_change(request, obj)

Finally, "Custom button" is added at the bottom of "Add" form and "Change" form for "Person" admin as shown below:最后,在“人员”管理员的“添加”表单和“更改”表单的底部添加了“自定义按钮” ,如下所示:

在此处输入图像描述

在此处输入图像描述

In addition, for "Person" admin , you can replace "changeform_view()" with "render_change_form()" set "context.update({"custom_button": True})" as shown below:另外,对于"Person" admin ,可以将" changeform_view()" 替换为"render_change_form()"设置"context.update({"custom_button": True})" ,如下所示:

# "admin.py"

from django.contrib import admin
from .models import Person

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    change_form_template = "admin/custom_change_form.html"
    
    def render_change_form(self, request, context, add=False, change=False, form_url="", obj=None):        
        
        context.update({"custom_button": True}) # Here

        return super().render_change_form(request, context, add, change, form_url, obj)

    def response_add(self, request, obj, post_url_continue=None):

        if "_custom_button" in request.POST:
            # Do something
            return super().response_add(request, obj, post_url_continue)
        else:
            # Do something
            return super().response_add(request, obj, post_url_continue)

    def response_change(self, request, obj):
        
        if "_custom_button" in request.POST:
            # Do something
            return super().response_change(request, obj)
        else:
            # Do something
            return super().response_change(request, obj)

Then, "Custom button" is added at the bottom of "Add" form and "Change" form for "Person" admin as well as shown below:然后,在“人员”管理员的“添加”表单和“更改”表单的底部添加“自定义按钮” ,如下所示:

在此处输入图像描述

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM