Различать носители ModelAdmin для добавления / изменения страниц в Django

#django #django-admin #media #modeladmin

#django #django-администратор #Медиафайлы #modeladmin

Вопрос:

Для инкапсуляции настраиваемых функций в Django admin я предоставляю пользовательский ModelAdmin класс, который на самом деле выглядит следующим образом:

 class ArticleAdmin(admin.ModelAdmin):
    class Media:
        js = ("my_code.js",)
  

Я отметил, что my_code.js загружается как на страницах добавления, так и на страницах изменения, но мне нужно загрузить его только на странице добавления. Возможно ли это сделать (и как)?

Комментарии:

1. Я думаю (но могу ошибаться), что это невозможно через class Media . Однако, если вы перезапишете конкретные шаблоны администратора, вы можете добиться такого поведения.

Ответ №1:

Не уверен, как StackOverflow нравится копаться в старых сообщениях, но я обнаружил, что это исследование для моей собственной проблемы, и нашел немного более элегантное решение, чем принятый ответ. Вы можете переопределить render_change_form метод для обновления context['media'] определения. Пример для этого вопроса:

 def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    if add:
        if context.has_key('media'):
            old_media = context['media']
        else:
            old_media = forms.Media()
        context.update({'media': old_media forms.Media(js=("js/SPD_media_admin.js",)) })
    return super(ArticleAdmin,self).render_change_form(request=request, context=context, add=add, change=change, form_url=form_url, obj=obj)
  

Это работает с Django 1.4. Заинтересованным читателям может потребоваться настроить args и kwargs в соответствии со спецификациями метода. context обычно не передается этому методу как kwarg иначе, я думаю, его можно было бы отредактировать без явного перечисления args . Надеюсь, это полезно для OP или потомков.

Ответ №2:

К сожалению, список файлов JavaScript для включения генерируется и назначается media контекстной переменной, предоставляемой функцией просмотра приложения администратора, которую вы не можете легко переопределить. Но вот одно не очень элегантное решение:

Просмотрите исходный код на странице добавления администратора для вашей текущей модели и скопируйте теги скрипта, которые импортируют файлы JavaScript, начиная со строки 14 (я использую Django 1.2). Вы увидите, куда их вставить, во фрагменте кода ниже.

Создайте свой собственный change_form.html шаблон в своем templates/admin/my_app/article каталоге и поместите в файл следующее содержимое:

 {% extends "admin/change_form.html" %}
{% block extrahead %}
{% url admin:jsi18n as jsi18nurl %}
<script type="text/javascript" src="{{ jsi18nurl|default:"../../../jsi18n/" }}"></script>
{% if add %}
{{ media }}
{% else %}
<!-- originally generated script tags: may differ depending on your model's fields -->
<script type="text/javascript" src="/media/admin/js/core.js"></script>
<script type="text/javascript" src="/media/admin/js/admin/RelatedObjectLookups.js"></script>
<script type="text/javascript" src="/media/admin/js/jquery.min.js"></script>
<script type="text/javascript" src="/media/admin/js/jquery.init.js"></script>
<script type="text/javascript" src="/media/admin/js/actions.min.js"></script>
<!-- end originally generated script tags -->
{% endif %}
{% endblock %}
  

Обратите внимание, что если вы добавите поле даты, например, в свою модель, поле не будет работать должным образом в форме изменения при редактировании записи, потому что не будет вызван необходимый calendar.js файл. Вам пришлось бы добавить его вручную, если бы вы внесли такое изменение.

Одной из альтернатив пойти дальше в этом направлении и восстановить утраченную динамичность было бы создание фильтра шаблона, в который вы могли бы передать media переменную и использовать регулярное выражение, например, для удаления ненужного тега script.