Django Admin:OneToOne关系作为内联?

Jia*_*aro 61 python django inline one-to-one django-admin

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

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

例如:

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

class MyProduct(models.Model):
    product = models.OneToOne(Product)
    ...
Run Code Online (Sandbox Code Playgroud)

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

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

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

admin.site.register(MyProduct, MyProductAdmin)
Run Code Online (Sandbox Code Playgroud)

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

这是自定义表单的唯一方法吗?

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

class AlbumAdmin(admin.ModelAdmin):
    fields = ('product__name',)
Run Code Online (Sandbox Code Playgroud)

Dan*_*man 74

完全可以使用内联来实现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)
Run Code Online (Sandbox Code Playgroud)

  • 我在同一条船上,我有一对一的字段,我需要在表之间切换外键,以便能够实现内联一对一.我宁愿不必更改我的数据库表以实现我想要的 - 将父模型内联到子项中.这有什么办法吗?理想情况下,看到它是一对一的关系,你应该以哪种方式做到这一点并不重要,它应该至少在技术上是可行的.没有做太多的管理员定制,我不确定我会进入什么! (14认同)
  • 哦,亲!= d (5认同)
  • 不幸的是,父模型已经注册了admin,我宁愿不去修补/分叉satchmo本身 (3认同)
  • 见我的进一步解释 (2认同)
  • 以这种方式添加多个子类型的任何建议(因为它们都是产品的OneToOne)? (2认同)
  • 我同意迈克尔的观点。对我来说,切换 One2One 的表会以一种不希望的方式完全改变逻辑。我不想仅仅为了管理中的内联工作而破坏应用程序的逻辑。 (2认同)
  • 和卡琳娜的情况一样。更改 One2One 字段的位置是不合逻辑的 (2认同)

Hen*_*nri 6

参考最后一个问题,什么是多个子类型的最佳解决方案.例如,具有子类型Book和子类型类CD的类Product.这里显示的方式是您必须编辑产品的常规项目以及书籍的子类型项目和CD的子类型项目.因此,即使您只想添加一本书,也可以获得CD的字段.如果添加子类型(例如DVD),则会获得三个子类型字段组,而实际上只需要一个子类型组,在上述示例中:books.


Ale*_*xey 6

也许使用继承代替OneToOne关系

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

class MyProduct(Product):
    .....
Run Code Online (Sandbox Code Playgroud)

或者使用代理类

class ProductProxy(Product)
    class Meta:
        proxy = True
Run Code Online (Sandbox Code Playgroud)

在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)
Run Code Online (Sandbox Code Playgroud)

在此变体中,您的产品将采用内联方式.

  • 你能扩展一下吗?我不清楚发生了什么 (2认同)