Djangopipe理 – 内联内联(或者,一次三个模型编辑)
我有一组看起来像这样的模型:
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, ]
我的目标是获得一个pipe理界面,可以让我在一页上编辑所有内容。 这个模型结构的最终结果是,事物被生成为一个视图+模板,看起来或多或less像:
<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 %}
我知道Djangopipe理员的内联技巧失败了,正如我所料。 有谁知道一种方法来允许这种三级模型编辑? 提前致谢。
您需要为LinkSectionInline
创build自定义表单和模板 。
像这样的东西应该工作的forms:
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
(刚刚从我头顶上掉下来,没有经过testing,但它应该让你朝着正确的方向前进。)
您的模板只需要适当地渲染窗体和form.link_formset。
Django嵌套内联就是为此而构build的。 用法很简单。
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)
我的build议实际上是改变你的模型。 为什么在Link
LinkSection
没有一个ForeignKey
? 或者,如果不是OneToMany,也许是ManyToMany
字段? pipe理界面将免费生成。 当然,如果链接在逻辑上与链接部分没有任何关系,我不build议这样做,但也许他们呢? 如果他们不这样做,请解释目标组织是什么。 (例如,每段3个链接固定或任意?
您可以创build一个新类,类似于TabularInline或StackedInline,它可以使用内联字段本身。
或者,您可以创build新的pipe理模板,专门用于您的模型。 但是,这当然推翻了pipe理界面的漂亮function。