Django Admin:OneToOne关系作为内联?

时间:2009-11-16 19:10:26

标签: python django django-admin inline one-to-one

我正在为一个satchmo应用程序整理管理员。 Satchmo使用OneToOne关系来扩展基础Product模型,我想在一个页面上编辑它。

可以将OneToOne关系作为内联吗?如果没有,最好的方法是将几个字段添加到我的管理员的给定页面,最终将保存到OneToOne关系中?

例如:

class Product(models.Model):
    name = models.CharField(max_length=100)
    ...

class MyProduct(models.Model):
    product = models.OneToOne(Product)
    ...

我为我的管理员尝试了这个但它不起作用,似乎期待一个外键:

class ProductInline(admin.StackedInline):
    model = Product
    fields = ('name',)

class MyProductAdmin(admin.ModelAdmin):
    inlines = (AlbumProductInline,)

admin.site.register(MyProduct, MyProductAdmin)

会引发此错误:<class 'satchmo.product.models.Product'> has no ForeignKey to <class 'my_app.models.MyProduct'>

执行此操作的唯一方法是Custom Form吗?

编辑:尝试使用以下代码直接添加字段...也不起作用:

class AlbumAdmin(admin.ModelAdmin):
    fields = ('product__name',)

4 个答案:

答案 0 :(得分:73)

完全可以使用内联来实现OneToOne关系。但是,定义关系的实际字段必须在内联模型上,而不是父模型 - 与ForeignKey的方式相同。切换它,它将工作。

在评论后编辑:您说父模型已经向管理员注册:然后取消注册并重新注册。

from original.satchmo.admin import ProductAdmin

class MyProductInline(admin.StackedInline):
    model = MyProduct

class ExtendedProductAdmin(ProductAdmin):
    inlines = ProductAdmin.inlines + (MyProductInline,)

admin.site.unregister(Product)
admin.site.register(Product, ExtendedProductAdmin)

答案 1 :(得分:6)

参考最后一个问题,什么是多个子类型的最佳解决方案。 E.g class Product with sub-type class Book和sub-type class CD。这里显示的方式是您必须编辑产品的常规项目以及书籍的子类型项目和CD的子类型项目。因此,即使您只想添加一本书,也可以获得CD的字段。如果你添加一个子类型,例如DVD,你得到三个子类型字段组,而实际上你只想要一个子类型组,在上面提到的例子中:books。

答案 2 :(得分:6)

也许使用继承代替OneToOne关系

class Product(models.Model):
    name = models.CharField(max_length=100)
    ...

class MyProduct(Product):
    .....

或使用代理类

class ProductProxy(Product)
    class Meta:
        proxy = True

在admin.py中

class MyProductInlines(admin.StackedInline):
    model = MyProduct

class MyProductAdmin(admin.ModelAdmin):
    inlines = [MyProductInlines]

    def queryset(self, request):
        qs = super(MyProductAdmin, self).queryset(request)
        qs = qs.exclude(relatedNameForYourProduct__isnone=True)
        return qs

admin.site.register(ProductProxy, MyProductAdmin)

在此变体中,您的产品将采用内联。

答案 3 :(得分:1)

您还可以尝试在OneToOneField上设置'parent_link = True'吗?

https://docs.djangoproject.com/en/dev/topics/db/models/#specifying-the-parent-link-field