53

我有一组看起来像这样的模型:

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

和一个看起来像这样的 admin.py:

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

我的目标是获得一个管理界面,让我可以在一页上编辑所有内容。这种模型结构的最终结果是,事物被生成为一个看起来或多或少类似于的视图+模板:

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

正如我所料,我知道 Django 管理员中的 inline-in-an-inline 技巧失败了。有谁知道允许这种三级模型编辑的方法?提前致谢。

4

4 回答 4

22

需要为. _ _LinkSectionInline

像这样的东西应该适用于表格:

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

(这只是从我的脑海中浮现出来,没有经过测试,但它应该让你朝着正确的方向前进。)

您的模板只需要适当地呈现表单和 form.link_formset。

于 2009-08-26T05:18:15.580 回答
5

Django-nested-inlines就是为此而构建的。用法很简单。

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)
于 2014-09-28T18:02:17.497 回答
1

我的建议实际上是改变你的模型。为什么不ForeignKey参加LinkLinkSection或者,如果它不是 OneToMany,也许是一个ManyToMany字段?管理界面将免费生成。当然,如果链接在逻辑上与链接部分没有任何关系,我不建议这样做,但也许它们有关系?如果他们不这样做,请解释预期的组织是什么。(例如,每个部分 3 个链接是固定的还是任意的?)

于 2009-04-04T14:05:51.500 回答
0

您可以创建一个类似于 TabularInline 或 StackedInline 的新类,该类本身能够使用内联字段。

或者,您可以专门为您的模型创建新的管理模板。但这当然推翻了管理界面的漂亮功能。

于 2009-08-25T17:29:16.367 回答