この質問のように、オブジェクトの混合体を返すクエリセットを使用できるようにしたいことを除いて:
>>> Product.objects.all()
[<SimpleProduct: ...>, <OtherProduct: ...>, <BlueProduct: ...>, ...]
Product.Meta.abstract
true に設定することも、異なるオブジェクトのクエリセットを単に OR することもできないことがわかりました。わかりましたが、これらはすべて共通クラスのサブクラスであるため、スーパークラスを非抽象として残しても、そのマネージャーに適切なクラスのオブジェクトを返させることができる限り、満足するはずです。django のクエリ コードはその役割を果たし、Product() を呼び出すだけです。をオーバーライドすると爆発することを除いて、十分に簡単に聞こえますが、モデルProduct.__new__
のせいだと推測してい__metaclass__
ます...これは、私が望むようにほとんど動作する非djangoコードです。
class Top(object):
_counter = 0
def __init__(self, arg):
Top._counter += 1
print "Top#__init__(%s) called %d times" % (arg, Top._counter)
class A(Top):
def __new__(cls, *args, **kwargs):
if cls is A and len(args) > 0:
if args[0] is B.fav:
return B(*args, **kwargs)
elif args[0] is C.fav:
return C(*args, **kwargs)
else:
print "PRETENDING TO BE ABSTRACT"
return None # or raise?
else:
return super(A).__new__(cls, *args, **kwargs)
class B(A):
fav = 1
class C(A):
fav = 2
A(0) # => None
A(1) # => <B object>
A(2) # => <C object>
しかし、django.db.models.Model
代わりにから継承すると失敗しますobject
:
File "/home/martin/beehive/apps/hello_world/models.py", line 50, in <module>
A(0)
TypeError: unbound method __new__() must be called with A instance as first argument (got ModelBase instance instead)
これは非常にくだらないバックトレースです。__new__
デバッガーでコードのフレームにステップインすることもできません。super(A, cls)
、Top
、 、および上記のすべてを、最初の引数として にsuper(A, A)
渡すことと組み合わせてさまざまに試しましたが、すべて役に立ちませんでした。なぜこれが私をそんなに激しく蹴っているのですか?これを修正するには、djangoのメタクラスを理解する必要がありますか?それとも、目的を達成するためのより良い方法がありますか?cls
__new__