2009-11-16 19 views
48

我正在组建一个satchmo应用程序的管理员。 Satchmo使用OneToOne关系来扩展基地Product模型,并且我想在一页上进行编辑。Django Admin:一对一关系作为内联?

可以将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',) 

回答

65

这是完全可以使用内嵌的OneToOne关系。但是,定义关系的实际字段必须位于内联模型中,而不是父类型 - 与对于ForeignKey完全相同。切换它,它会工作。

在评论后编辑:你说父模型已经注册了admin:然后取消注册并重新注册。

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) 
+2

不幸父模型已经与管理员登记,我宁愿不走下车修补/分叉的Satchmo本身 – Jiaaro 2009-11-16 20:15:41

+2

见我进一步解释 – 2009-11-16 20:30:23

+4

哦,亲小费! = D – Jiaaro 2009-11-17 13:17:19

4

参考最后一个问题,多种子类型的最佳解决方案是什么。 E.g类具有子类型Book和子类CD的产品。此处显示的方式必须编辑产品的一般项目,以及书籍的子类型项目和CD的子类型项目。所以,即使您只想添加一本书,您也可以获得CD的字段。如果您添加了一个子类型,例如DVD中,您会看到三个子类型的字段组,但实际上您只需要一个子类型组,如上所述:书籍。

5

也许使用继承,而不是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) 

在这个变型产品将成为在线。

+1

你可以扩展一下吗?目前还不清楚这是怎么回事 – bryanph 2015-11-04 09:17:47