Как добавить "свернуть" в Django StackedInline

Таким же образом вы можете добавить 'classes': ['collapse'] в один из ваших полей ModelAdmin, я хотел бы иметь возможность компоновки Inline Model Admin.

Этот билет, Свернуть в админ-интерфейсе для встроенных связанных объектов, обсуждает именно то, что я хочу выполнить. Но в то же время, что лучше всего работает, пока мы ждем следующего релиза?

FYI: Я придумал решение, но я думаю, что существует лучший. Я позволю голосованию позаботиться об этом.

Ответы

Ответ 1

Я придумал это решение, используя jQuery, который работает на TabularInline

var selector = "h2:contains('TITLE_OF_INLINE_BLOCK')";
$(selector).parent().addClass("collapsed");
$(selector).append(" (<a class=\"collapse-toggle\" id=\"customcollapser\" href=\"#\"> Show </a>)");
$("#customcollapser").click(function() {
    $(selector).parent().toggleClass("collapsed");
});

Ответ 2

Вы можете использовать grappelli - который поддерживает свертывающиеся поля. Он использует решение так же, как решения, упомянутые выше, но javascript/кодирование уже сделано - вам просто нужно добавить "классы": (свернуть закрыто ',) на ваш набор полей (см. http://readthedocs.org/docs/django-grappelli/en/latest/customization.html)

например:

class ModelOptions(admin.ModelAdmin):
    fieldsets = (
        ('', {
            'fields': ('title', 'subtitle', 'slug', 'pub_date', 'status',),
        }),
        ('Flags', {
            'classes': ('grp-collapse grp-closed',),
            'fields' : ('flag_front', 'flag_sticky', 'flag_allow_comments', 'flag_comments_closed',),
        }),
        ('Tags', {
            'classes': ('grp-collapse grp-open',),
            'fields' : ('tags',),
        }),
    )

class StackedItemInline(admin.StackedInline):
    classes = ('grp-collapse grp-open',)

class TabularItemInline(admin.TabularInline):
    classes = ('grp-collapse grp-open',)

Ответ 3

Вот как я решил это, но он чувствует себя слишком сильно, как взломать (для взлома).

Я использовал jQuery, размещенный из API Google, для изменения DOM, используя Django собственный 'show/hide' script. Если вы посмотрите на источник html страницы администратора, последний загруженный script следующий:

<script type="text/javascript" src="/media/admin/js/admin/CollapsedFieldsets.js"></script>

Комментарии в этом файле дали мне идею: Leverage Определения модели ModelAdmin для загрузки моего собственного dom-altering script.

from django.contrib import admin
from django.contrib.admin.sites import AdminSite
from myapp.models import *
import settings
media = settings.MEDIA_URL

class MyParticularModelAdmin(admin.ModelAdmin):
    # .....
    class Media:
          js = ('http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js',
              media+'js/addCollapseToAllStackedInlines.js')
# .....

И затем внутри ссылочного файла javascript:

// addCollapseToAllStackedInlines.js
$(document).ready(function() {
  $("div.inline-group").wrapInner("<fieldset class=\"module aligned collapse\"></fieldset>");
});

Конечные результаты работают только на StackedInline, NOT TabularInline.

Ответ 4

Несколько улучшений ответа gerdemb. Добавляет текст "Показать" и "Скрыть" соответствующим образом и позволяет заранее указать табличные встроенные имена в списке:

$(document).ready(function(){
var tabNames = ['Inline Name 1', 'Inline Name 2', 'Inline Name 3'];
for (var x in tabNames)
{
    var selector = "h2:contains(" + tabNames[x] + ")";
    $(selector).parent().addClass("collapsed");
    $(selector).append(" (<a class=\"collapse-toggle\" id=\"customcollapser\""+ x + " href=\"#\"> Show </a>)");
};    
$(".collapse-toggle").click(function(e) {
    $(this).parent().parent().toggleClass("collapsed");
    var text = $(this).html();
    if (text==' Show ') {
        $(this).html(' Hide ');
        }
    else {
        $(this).html(' Show ');
    };
    e.preventDefault();
});
});

Ответ 5

Мое текущее решение, основанное на других, перечисленных здесь, имеет следующие функции:

  • Только сворачивает сложенные строки
  • Не сворачивает строки, содержащие ошибку
  • Не сворачивает "пустой" встроенный.

Это решение Javascript, что означает, что его нужно каким-либо образом вставлять в вашу страницу/шаблон.

Он требует, чтобы jQuery загружался на страницу к моменту ее выполнения. Современные версии Django имеют это.

$(function(){
  // Find all stacked inlines (they have an h3, with a span.inline_label).
  // Add a link to toggle collapsed state.
  $('.inline-group h3 .inline_label').append(' (<a class="collapse-toggle" href="#">Show</a>)');
  // Collapse all fieldsets that are in a stacked inline (not .tabular)
  $('.inline-group :not(.tabular) fieldset').addClass('collapsed');
  // Click handler: toggle the related fieldset, and the content of our link.
  $('.inline-group h3 .inline_label .collapse-toggle').on('click', function(evt) {
    $(this).closest('.inline-related').find('fieldset').toggleClass('collapsed');
    text = $(this).html();
    if (text=='Show') {
      $(this).html('Hide');
    } else {
      $(this).html('Show');
    };
    evt.preventDefault();
    evt.stopPropagation();
  });
  // Un-collapse empty forms, otherwise it 2 clicks to create a new one.
  $('.empty-form .collapse-toggle').click();
  // Un-collapse any objects with errors.
  $('.inline-group .errors').closest('.inline-related').find('.collapse-toggle').click();
});

Ответ 6

Из django 1.10 Теперь мы можем добавить дополнительные классы css в InlineModelAdmin.

Список или кортеж, содержащий дополнительные классы CSS для применения к набору полей, который отображается для строк. По умолчанию - None. Как и в классах, настроенных в полях, встроенные строки с классом collapse будут сначала свернуты, а их заголовок будет иметь небольшую ссылку "показать".

Docs