Cómo agregar ''colapsar'' a un Django StackedInline
django-admin collapse (7)
Así es como lo resolví, pero se siente demasiado como un hack (para un hack).
Usé jQuery alojado desde las API de Google para modificar el DOM, aprovechando el propio script ''mostrar / ocultar'' de Django. Si miras la fuente html de una página de administración, la última secuencia de comandos cargada es la siguiente:
<script type="text/javascript" src="/media/admin/js/admin/CollapsedFieldsets.js"></script>
Los comentarios en ese archivo me dieron la idea: aprovechar las definiciones de medios de ModelAdmin para cargar mi propio script de modificación de dominio .
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'')
# .....
Y luego dentro del archivo javascript referenciado:
// addCollapseToAllStackedInlines.js
$(document).ready(function() {
$("div.inline-group").wrapInner("<fieldset class=/"module aligned collapse/"></fieldset>");
});
Los resultados finales solo funcionan en StackedInline, NO en TabularInline.
De la misma manera que puede agregar ''clases'': [''colapsar''] a uno de sus campos de ModelAdmin, me gustaría poder tener un administrador de modelo en línea que sea plegable.
Este ticket, Contraer en la interfaz de administración para objetos relacionados en línea , explica exactamente lo que quiero lograr. Pero mientras tanto, ¿cuál es el mejor trabajo mientras esperamos el próximo lanzamiento?
FYI: He encontrado una solución, pero creo que existe una mejor. Dejaré que la votación se encargue de ello.
Desde django 1.10, ahora también podemos agregar clases de css adicionales a InlineModelAdmin.
Una lista o tupla que contiene clases de CSS adicionales para aplicar al conjunto de campos que se representa para los inlines. Por defecto, ninguno. Al igual que con las clases configuradas en los conjuntos de campos, las líneas con una clase colapsada se colapsarán inicialmente y su encabezado tendrá un pequeño enlace "mostrar".
En Django de hoy en día esto es tan fácil como lo siguiente:
class FooInline(admin.StackedInline):
model = Foo
classes = [''collapse'']
Mi solución actual, basada en otras enumeradas aquí, tiene las siguientes características:
- Solo colapsa apilados en linea.
- No contrae inlines que contienen un error.
- No colapsa el ''vacío'' en línea.
Es una solución de Javascript, lo que significa que debe ser inyectado en su página / plantilla de alguna manera.
Requiere que jQuery se cargue en la página antes de que se ejecute. Las versiones modernas de Django tienen esto.
$(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''s 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();
});
Puedes usar grappelli, que admite el colapso de los campos. Utiliza una solución muy parecida a las soluciones mencionadas anteriormente, pero javascript / coding ya está hecho, solo tiene que agregar ''classes'' :( collapse closed '',) a su fieldset (consulte http://readthedocs.org/docs/django-grappelli/en/latest/customization.html )
por ejemplo:
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'',)
Un par de mejoras en la respuesta de gerdemb. Agrega el texto ''Mostrar'' y ''Ocultar'' adecuadamente, y le permite especificar los nombres tabulares en línea en una lista de antemano:
$(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();
});
});
Se me ocurrió esta solución utilizando jQuery que funciona en 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");
});