将 "Save as new" 按钮添加到 Django 外部对象编辑弹出窗口
Add "Save as new" button to Django foreign object edit popup
在 Django 中,我们有 ModelAdmin 的 save_as
参数,它可以在某些对象的管理员站点编辑页面上启用 "Save as new" 按钮。
但是当对象(Model1 实例)默认与其他模型(Model2)相关时,我想按以下方式编辑 Model2 实例:对当前关系采用默认值(取决于 Model2 实例字段) Model1实例并编辑它的一些字段,我单击编辑按钮并出现弹出窗口,我可以在其中更改一些字段,但不能将该对象另存为新对象,所以我有 2 个选项:破坏默认对象或复制粘贴每个字段将该相关对象放入 "Add new" 弹出窗口。
我想将 "Save as new" 按钮添加到“编辑”弹出窗口中。
我发现,用name="_saveasnew"
和value=1
添加隐藏输入实际上确实保存了另一个模型,但是如何用特殊按钮添加它呢?
此外,那个按钮上有一个特殊的块用于弹出 window,正如我所见:https://github.com/django/django/blob/1.8/django/contrib/admin/templatetags/admin_modify.py#L39(是的,我们使用 Django 1.8 :()
最佳解决方案是什么:编辑模板还是编辑标签本身?
正确的解决方案是使用您自己的 submit_row
模板标签弹出 window,为此,您必须覆盖 admin/change_form.html
模板的块:submit_buttons_top
和submit_buttons_bottom
:
{% extends "admin/change_form.html" %}
{% load YOUR_TEMPLATE_TAGS %}
{% block submit_buttons_top %}{% YOUR_SUBMIT_ROW_TAG %}{% endblock %}
{% block submit_buttons_bottom %}{% YOUR_SUBMIT_ROW_TAG %}{% endblock %}
新 submit_row
标签代码的主要区别是更改了上下文键:'show_save_as_new': change and save_as,
YOUR_TEMPLATE_TAGS.py
的代码可能如下所示:
from django import template
register = template.Library()
@register.inclusion_tag('admin/submit_line.html', takes_context=True)
def YOUR_SUBMIT_ROW_TAG(context):
"""
Displays the row of buttons for delete and save.
HINT: override of default django `submit_row` tag, changes:
`save as new` button is displayed for popup.
"""
opts = context['opts']
change = context['change']
is_popup = context['is_popup']
save_as = context['save_as']
new_context = {
'opts': opts,
'show_delete_link': (
not is_popup and context['has_delete_permission'] and
change and context.get('show_delete', True)
),
'show_save_as_new': change and save_as,
'show_save_and_add_another': (
context['has_add_permission'] and not is_popup and
(not save_as or context['add'])
),
'show_save_and_continue': not is_popup and context['has_change_permission'],
'is_popup': is_popup,
'show_save': True,
'preserved_filters': context.get('preserved_filters'),
}
if context.get('original') is not None:
new_context['original'] = context['original']
return new_context
在 Django 中,我们有 ModelAdmin 的 save_as
参数,它可以在某些对象的管理员站点编辑页面上启用 "Save as new" 按钮。
但是当对象(Model1 实例)默认与其他模型(Model2)相关时,我想按以下方式编辑 Model2 实例:对当前关系采用默认值(取决于 Model2 实例字段) Model1实例并编辑它的一些字段,我单击编辑按钮并出现弹出窗口,我可以在其中更改一些字段,但不能将该对象另存为新对象,所以我有 2 个选项:破坏默认对象或复制粘贴每个字段将该相关对象放入 "Add new" 弹出窗口。
我想将 "Save as new" 按钮添加到“编辑”弹出窗口中。
我发现,用name="_saveasnew"
和value=1
添加隐藏输入实际上确实保存了另一个模型,但是如何用特殊按钮添加它呢?
此外,那个按钮上有一个特殊的块用于弹出 window,正如我所见:https://github.com/django/django/blob/1.8/django/contrib/admin/templatetags/admin_modify.py#L39(是的,我们使用 Django 1.8 :() 最佳解决方案是什么:编辑模板还是编辑标签本身?
正确的解决方案是使用您自己的 submit_row
模板标签弹出 window,为此,您必须覆盖 admin/change_form.html
模板的块:submit_buttons_top
和submit_buttons_bottom
:
{% extends "admin/change_form.html" %}
{% load YOUR_TEMPLATE_TAGS %}
{% block submit_buttons_top %}{% YOUR_SUBMIT_ROW_TAG %}{% endblock %}
{% block submit_buttons_bottom %}{% YOUR_SUBMIT_ROW_TAG %}{% endblock %}
新 submit_row
标签代码的主要区别是更改了上下文键:'show_save_as_new': change and save_as,
YOUR_TEMPLATE_TAGS.py
的代码可能如下所示:
from django import template
register = template.Library()
@register.inclusion_tag('admin/submit_line.html', takes_context=True)
def YOUR_SUBMIT_ROW_TAG(context):
"""
Displays the row of buttons for delete and save.
HINT: override of default django `submit_row` tag, changes:
`save as new` button is displayed for popup.
"""
opts = context['opts']
change = context['change']
is_popup = context['is_popup']
save_as = context['save_as']
new_context = {
'opts': opts,
'show_delete_link': (
not is_popup and context['has_delete_permission'] and
change and context.get('show_delete', True)
),
'show_save_as_new': change and save_as,
'show_save_and_add_another': (
context['has_add_permission'] and not is_popup and
(not save_as or context['add'])
),
'show_save_and_continue': not is_popup and context['has_change_permission'],
'is_popup': is_popup,
'show_save': True,
'preserved_filters': context.get('preserved_filters'),
}
if context.get('original') is not None:
new_context['original'] = context['original']
return new_context