我已经为我的模型定义了一个自定义管理操作,它可以完美地按预期工作。我还在SO上看了多个向管理员更改表单页面添加按钮的方法。只有我缺少的一步是如何在更改表单页面中创建一个按钮,使用当前对象执行我的自定义管理操作。
目标是允许管理员单独检查每个对象并对其执行操作,而无需返回列表视图,选择检查对象,并从列表中执行操作。
我的自定义管理操作如下所示:
def admin_apply_change(modeladmin, request, queryset):
# loop over objects in query set and perform action
我假设有一种简单而干净的方法可以在管理员更改表单中调用此操作,其中queryset
只包含管理员正在查看的当前打开的对象。
注意:如果按钮位于更改表单的底部,位于Save
按钮旁边,而不是位于History
的顶部,而不是非常明显,则会更感兴趣。
请参阅Remi的答案以获得解决方案。为了使其工作,需要进行以下更正:
1:在response_change
的覆盖中,缺少某些变量的初始化:
opts = self.model._meta
pk_value = obj._get_pk_val()
preserved_filters = self.get_preserved_filters(request)
2:新的包含标记custom_submit_row
应放在模板标签中,而不是放在管理员中(参见docs for custom templatetags)
3:这是你可以放松一段时间的疏忽。在change_form.html
中,您不仅需要更改建议的行:
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
也是submit_row
出现在底部的更重要的一行:
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
(它位于change_form.html
)
答案 0 :(得分:15)
您可以查看change_form_template并将其设置为自己的自定义模板并覆盖response_change
方法:
class MyModelAdmin(admin.ModelAdmin):
# A template for a customized change view:
change_form_template = 'path/to/your/custom_change_form.html'
def response_change(self, request, obj):
opts = self.model._meta
pk_value = obj._get_pk_val()
preserved_filters = self.get_preserved_filters(request)
if "_customaction" in request.POST:
# handle the action on your obj
redirect_url = reverse('admin:%s_%s_change' %
(opts.app_label, opts.model_name),
args=(pk_value,),
current_app=self.admin_site.name)
redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
return HttpResponseRedirect(redirect_url)
else:
return super(MyModelAdmin, self).response_change(request, obj)
从change_form.html
复制site-packages/django/contrib/admin/templates/change_form.html
并修改第44行
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
到
{% if save_on_top %}{% block submit_buttons_top %}{% custom_submit_row %}{% endblock %}{% endif %}
同时检查一下:
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
就在javascript块之上。
然后,您可以在admin.py中的某处注册新的包含标记,或将其添加到templatetags:
@register.inclusion_tag('path/to/your/custom_submit_line.html', takes_context=True)
def custom_submit_row(context):
"""
Displays the row of buttons for delete and save.
"""
opts = context['opts']
change = context['change']
is_popup = context['is_popup']
save_as = context['save_as']
ctx = {
'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': not is_popup and 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:
ctx['original'] = context['original']
return ctx
custom_submit_line.html
的内容:
{% load i18n admin_urls %}
<div class="submit-row">
{% if show_save %}<input type="submit" value="{% trans 'Save' %}" class="default" name="_save" />{% endif %}
{% if show_delete_link %}
{% url opts|admin_urlname:'delete' original.pk|admin_urlquote as delete_url %}
<p class="deletelink-box"><a href="{% add_preserved_filters delete_url %}" class="deletelink">{% trans "Delete" %}</a></p>
{% endif %}
{% if show_save_as_new %}<input type="submit" value="{% trans 'Save as new' %}" name="_saveasnew" />{% endif %}
{% if show_save_and_add_another %}<input type="submit" value="{% trans 'Save and add another' %}" name="_addanother" />{% endif %}
{% if show_save_and_continue %}<input type="submit" value="{% trans 'Save and continue editing' %}" name="_continue" />{% endif %}
<input type="submit" value="{% trans 'Custom Action' %}" name="_customaction" />
</div>
它有很多代码,但主要是复制/粘贴。希望有所帮助。
答案 1 :(得分:7)
大多数人可能不假思索地这样做,但从答案中不清楚管理员更改表格应该简单地扩展而不是完全覆盖。
custom_change_form.html
{% extends "admin/change_form.html" %}
{% if save_on_top %}{% block submit_buttons_top %}{% custom_submit_row %}{% endblock %}{% endif %}
{% block submit_buttons_bottom %}{% custom_submit_row %}{% endblock %}
答案 2 :(得分:1)
或者,您可以扩展 submit_line.html 文件,添加您的自定义按钮(位于更改页面的顶部和底部)。
您的文件 templates / adminyour_app_name / your_model_name.html 将以:
开头{% extends "admin/submit_line.html" %}
{% load i18n admin_urls %}
<div class="submit-row">
{% block submit-row %}
... YOUR BUTTONS HERE ...
{% endblock %}
</div>