2016-05-26 14 views
0

Djangoの継承は私のニーズに合っていないので、私は本質的に私自身の継承スキームを考え出しています。Django、OneToOne関連のフィールドを自分のフィールドとして扱います

私は親テーブル(クラス)の共通データフィールドを保持したいと思います。
サブクラスは別のテーブルに独自の追加データを持ちます。

class ProductBase(models.Model): 

    common = models.IntegerField() 

    def get_price(self): 
     return some_price 


class FooProduct(ProductBase): 

    # no field because I'm proxy 

    class Meta: 
     proxy = True 

    def get_price(self): 
     return price_using_different_logic 


class FooExtra(models.Model): 

    base = models.OneToOneField(ProductBase, primary_key=True) 
    phone = models.CharField(max_length=10) 

私の質問は、fooがFooExtraのフィールドを持っているかのように扱うことができるだろう、とは?

私は次のようなものをやってみたい

...

foo = FooProduct.objects.create() 

foo.phone = "3333" # as django does with its multiple inheritance 
foo.save() 
FooProduct.objects.filter(phone="3333") 

私は別の種類の製品を一覧表示したい(データ)ので、私はそれらを一緒にリストする必要があり

  1. 、抽象基底継承が外されている

  2. リストから、ProductBase.objects.all()を反復処理するときに、各モデルをポリモーフィックモデルとして扱いたいと思います。product.get_price()は適切なclaを使用しますsseの方法。

  3. と私がしたい場合にのみ、私は.select_related('fooextra')

Django-polymorphicのようなもので(addtionalのテーブルデータを取得するには、私が欲しいものに近い(発生させずにする必要がない場合は参加)が、 Djangoの標準の継承に別の何かをしたいように、それはむしろ、それは私がそれを使用して怖いんし、私はそれが#3を失敗した何を考えて不明瞭である。

+0

Djangoのデフォルトのモデル継承は、あなたにとってうまくいかないのはどういう意味ですか? – Ben

+0

@Ben:問題に対処するために質問を編集しました。 – eugene

答えて

1

それはいないようです。

class ProductBase(models.Model): 
    common1 = models.IntegerField() 
    common2 = models.IntegerField() 

class FooProduct(ProductBase): 
    fooextra = models.IntegerField() 

class BarProduct(ProductBase): 
    barextra = models.IntegerField() 

あなたがそれぞれのインスタンスを作成する場合:

foo1 = FooProduct(common1=1, common2=1, fooextra=1) 
foo2 = FooProduct(common1=1, common2=1, fooextra=2) 
bar1 = BarProduct(common1=1, common2=1, barextra=1) 
bar2 = BarProduct(common1=1, common2=1, barextra=2) 

あなたができるすべての製品をループ:

for product in ProductBase.objects.all(): 
    print product.common1, product.common2 

を実際にFooProductあるProductBaseオブジェクトから、あなたがカスタムフィールドを取得することができます

product.foo.fooextra 

実際にBarProductProductBaseオブジェクトから、あなたはカスタムフィールド:

product.bar.barextra 

あなたはまだ照会行うことができます。

foo = FooProduct.objects.get(fooextra=1) 
bar = BarProduct.objects.get(barextra=2) 

そして、あなたはそれらのオブジェクトに直接、共通のフィールドにアクセスすることができた:

foo.common1 
bar.common2 

あなたはdjango-model-utilsからInheritanceManagerを使用することができますクエリなどをより詳細に制御する必要がある場合は、これもポイント3に対処する必要があります。ProductBase.objects.filter(...).select_subclasses()FooProductと0123オブジェクトはProductBaseの代わりにオブジェクトです。

+0

素敵な答え、あなたは1分で私を打ち負かしました:-) – mastazi

+0

@mastazi:ありがとう;-) – Ben

+0

基本は 'def price(self)'を持っていて、 'foo'はそれ自身のバージョン' ProductBase.objects.all(): 'は多態的な価格を使用しません。 – eugene

1

私がよく理解している場合、継承が必要で、子クラスに固有のフィールドを別のテーブルに入れたいとします。

class Base(models.Model): 
    common = models.IntegerField() 


class Foo(Base): 
    phone = models.CharField(max_length=10) 

このリンクで説明したように、:https://docs.djangoproject.com/en/1.9/topics/db/models/#multi-table-inheritanceなどのマニュアルに指定されているよう 私の知る限りでは、あなたはあなただけのマルチテーブル継承を実装することができ、それを達成するためにプロキシクラスを必要としません自動的に1対1の関係が作成されます。もちろん、上記の例のようにfoo.phone = "3333"fooFooのタイプです)を行うことができます。そして、きちんとしたことは、foo.commonにアクセスすることができ、あなたの例ではfoo.base.commonでした。

関連する問題