tutorial personalizar modelos desde datos cero python django django-models django-admin inlines

python - personalizar - Administrador de Django: líneas en línea(o tres versiones de modelos a la vez)



modelos en django (4)

Tengo un conjunto de modelos que se ven así:

class Page(models.Model): title = models.CharField(max_length=255) class LinkSection(models.Model): page = models.ForeignKey(Page) title = models.CharField(max_length=255) class Link(models.Model): linksection = models.ForeignKey(LinkSection) text = models.CharField(max_length=255) url = models.URLField()

y un admin.py que se ve así:

class LinkInline(admin.TabularInline): model = Link class LinkSectionInline(admin.TabularInline): model = LinkSection inlines = [ LinkInline, ] class PageAdmin(admin.ModelAdmin): inlines = [ LinkSectionInline, ]

Mi objetivo es obtener una interfaz de administrador que me permita editar todo en una página. El resultado final de esta estructura de modelo es que las cosas se generan en una plantilla de vista + que se parece más o menos a:

<h1>{{page.title}}</h1> {% for ls in page.linksection_set.objects.all %} <div> <h2>{{ls.title}}</h2> <ul> {% for l in ls.link_set.objects.all %} <li><a href="{{l.url}}">{{l.title}}</a></li> {% endfor %} </ul> </div> {% endfor %}

Sé que el truco en línea en una línea falla en el administrador de Django, como esperaba. ¿Alguien sabe de una manera de permitir este tipo de edición de modelo de tres niveles? Gracias por adelantado.


Mi recomendación sería cambiar tu modelo. ¿Por qué no tener una ForeignKey en Link a LinkSection ? O, si no es OneToMany, quizás un campo ManyToMany ? La interfaz de administración generará eso de forma gratuita. Por supuesto, no recomiendo esto si los enlaces lógicamente no tienen nada que ver con las secciones de enlace, pero ¿quizás sí? Si no lo hacen, explique cuál es la organización prevista. (Por ejemplo, ¿hay 3 enlaces por sección fijos o arbitrarios?)


Puede crear una nueva clase, similar a TabularInline o StackedInline, que pueda usar campos en línea.

Alternativamente, puede crear nuevas plantillas de administrador, específicamente para su modelo. Pero eso, por supuesto, anula las características ingeniosas de la interfaz de administración.


Django-nested-inlines está hecho para esto. El uso es simple.

from django.contrib import admin from nested_inlines.admin import NestedModelAdmin, NestedStackedInline, NestedTabularInline from models import A, B, C class MyNestedInline(NestedTabularInline): model = C class MyInline(NestedStackedInline): model = B inlines = [MyNestedInline,] class MyAdmin(NestedModelAdmin): pass admin.site.register(A, MyAdmin)


LinkSectionInline crear un form y una template para LinkSectionInline .

Algo así debería funcionar para la forma:

LinkFormset = forms.modelformset_factory(Link) class LinkSectionForm(forms.ModelForm): def __init__(self, **kwargs): super(LinkSectionForm, self).__init__(**kwargs) self.link_formset = LinkFormset(instance=self.instance, data=self.data or None, prefix=self.prefix) def is_valid(self): return (super(LinkSectionForm, self).is_valid() and self.link_formset.is_valid()) def save(self, commit=True): # Supporting commit=False is another can of worms. No use dealing # it before it''s needed. (YAGNI) assert commit == True res = super(LinkSectionForm, self).save(commit=commit) self.link_formset.save() return res

(Eso simplemente salió de mi cabeza y no ha sido probado, pero debería ayudarte a avanzar en la dirección correcta).

Su plantilla solo necesita representar la forma y el formulario.link_formset de manera apropiada.