72

satchmoアプリケーションの管理者をまとめています。SatchmoはOneToOneリレーションを使用して基本Productモデルを拡張しているので、すべてを1ページで編集したいと思います。

インラインとして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'>

これを行う唯一の方法はカスタムフォームですか?

編集:フィールドを直接追加するために次のコードを試しました...これも機能しません:

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

4 に答える 4

82

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)

アップデート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
于 2009-11-16T19:49:49.570 に答える
9

たぶん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)

このバリアントでは、製品はインラインになります。

于 2012-09-28T12:42:57.390 に答える
5

最後の質問を参照すると、複数のサブタイプに最適なソリューションは何でしょうか。たとえば、サブタイプクラスの本とサブタイプクラスのCDを持つクラスの製品。ここに示す方法では、製品の一般的なアイテムに加えて、本のサブタイプのアイテムとCDのサブタイプのアイテムを編集する必要があります。したがって、本を追加するだけの場合でも、CDのフィールドも取得できます。DVDなどのサブタイプを追加すると、3つのサブタイプフィールドグループが取得されますが、前述の例では、実際には1つのサブタイプグループのみが必要です。

于 2010-03-14T00:24:43.000 に答える
2

OneToOneFieldに「parent_link=True」を設定してみることもできますか?

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

于 2012-12-14T10:57:55.273 に答える