Django admin - inlines em linha (ou, três modelo de edição de uma vez)

votos
51

Eu tenho um conjunto de modelos que se parecem com isto:

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()

e um admin.py parecida com esta:

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

Meu objetivo é fazer com que uma interface de administração que me permite editar tudo em uma página. O resultado final desta estrutura do modelo é que as coisas são gerados em uma exibição + modelo que parece mais ou menos assim:

<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 %}

Eu sei que o truque inline-em-um-inline falhar na administração do Django, como eu esperava. Alguém sabe de uma maneira de permitir que este tipo de três edição modelo de nível? Desde já, obrigado.

Publicado 31/03/2009 em 20:20
fonte usuário
Em outras línguas...                            


4 respostas

votos
20

Você precisa criar um personalizado forma e modelo para o LinkSectionInline.

Algo como isso deve funcionar para a 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

(Isso só veio em cima da minha cabeça e não é testado, mas deverá fazê-lo indo na direção certa.)

O modelo só precisa tornar o formulário e form.link_formset adequadamente.

Respondeu 26/08/2009 em 06:18
fonte usuário

votos
4

Django-nested-inlines é construído apenas para este. O uso é simples.

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)
Respondeu 28/09/2014 em 19:02
fonte usuário

votos
1

Minha recomendação seria realmente mudar o seu modelo. Por que não ter um ForeignKeyem Linkque LinkSection? Ou, se não é OneToMany, talvez um ManyToManycampo? A interface de administração irá gerar isso de graça. Claro, eu não recomendo isso se links não logicamente tem nada a ver com seções de links, mas talvez eles fazem? Se não o fizerem, por favor, explique o que a organização pretende é. (Por exemplo, é de 3 ligações pela secção fixa ou arbitrária?)

Respondeu 04/04/2009 em 15:05
fonte usuário

votos
0

Você pode criar uma nova classe, semelhante ao TabularInline ou StackedInline, que é capaz de usar o próprio campos inline.

Alternativamente, você pode criar novos modelos de administração, especificamente para o seu modelo. Mas isso, claro, anula as características interessantes da interface de administração.

Respondeu 25/08/2009 em 18:29
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more