Django Admin:作为内联的 OneToOne 关系?

新手上路,请多包涵

我正在为 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',)

原文由 Jiaaro 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 534
2 个回答

完全有可能对 OneToOne 关系使用内联。然而,定义关系的实际字段必须在内联模型上,而不是父模型上——就像外键一样。将其切换过来,它将起作用。

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

 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)


2020 年更新(Django 3.1.1)

此方法仍然有效,但某些类型在新的 Django 版本中发生了变化,因为 inlinesExtendedProductAdmin 现在应该添加为列表而不是元组,如下所示:

 class ExtendedProductAdmin(ProductAdmin):
    inlines = ProductAdmin.inlines + [MyProductInline]

或者你会得到这个错误:

     inlines = ProductAdmin.inlines + (MyProductInline,)
TypeError: can only concatenate list (not "tuple") to list

原文由 Daniel Roseman 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

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

原文由 Alexey 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题