Django: как добавить пользовательскую кнопку на страницу формы изменения администратора, которая выполняет действие администратора?
я уже определил пользовательское действие администратора для моей модели, которая работает отлично, как ожидалось. Я также рассмотрел несколько способов добавления кнопки на страницу формы изменения администратора здесь, на SO. Единственный шаг, который мне не хватает, - это как заставить кнопку на странице изменить форму выполнить мое пользовательское действие администратора с текущим объектом.
цель состоит в том, чтобы позволить администратору проверять каждый объект индивидуально и выполнять действие над ними без необходимости возвращаться к списку, выбирая проверяемый объект и выполнение действия из списка.
мои пользовательские действия админа выглядит так:
def admin_apply_change(modeladmin, request, queryset):
# loop over objects in query set and perform action
я предполагаю, что есть простой и чистый способ вызова этого действия в форме изменения администратора, где queryset
будет содержать только текущий открытый объект, на который смотрит администратор.
Примечание: было бы предпочтительнее, если кнопка находится в нижней части этой формы, рядом с Save
кнопка вместо того, чтобы быть наверху с History
что не очень видимый.
решение
Посмотреть ответ к Реми для решения. Чтобы заставить его работать, необходимы следующие исправления:
1: в переопределении response_change
инициализация некоторых переменных отсутствует:
opts = self.model._meta
pk_value = obj._get_pk_val()
preserved_filters = self.get_preserved_filters(request)
2: новый тег включения custom_submit_row
следует размещать в templatetags, а не в admin (см. документы для пользовательских 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 %}
(он расположен чуть выше блока javascript в change_form.html
)
2 ответов
вы может взглянем на!--11-->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 %}
to
{% 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>
это много кода, но в основном копировать/вставить. Надеюсь, это поможет.
большинство людей, вероятно, делают это, не думая, хотя из ответа не было ясно, что форма изменения администратора должна быть просто расширена, а не полностью перезаписана.
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 %}