Al igual que en this question, excepto que quiero ser capaz de tener QuerySets que devuelven un cuerpo mixto de objetos:modelos de Django subclases con QuerySets integrados
>>> Product.objects.all()
[<SimpleProduct: ...>, <OtherProduct: ...>, <BlueProduct: ...>, ...]
me di cuenta de que no puedo acaba de establecer Product.Meta.abstract
a cierto o de lo contrario solo O O BIEN conjunto de conjuntos de objetos diferentes. Bien, pero todas son subclases de una clase común, así que si dejo su superclase como no abstracta, debería estar contento, siempre y cuando pueda hacer que su administrador devuelva los objetos de la clase adecuada. El código de consulta en django hace su trabajo, y solo hace llamadas a Product(). Suena bastante fácil, excepto que explota cuando puedo reemplazar Product.__new__
, supongo que debido a la __metaclass__
en el Modelo ... Aquí es código no Django que se comporta más o menos como lo quiero:
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>
Pero eso no funciona si heredar de django.db.models.Model
en lugar de 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)
Cuál es la traza sobre todo de mierda; Tampoco puedo entrar en el marco de mi código __new__
en el depurador. He intentado varias veces super(A, cls)
, Top
, super(A, A)
, y todo lo anterior en combinación con pasar cls
como primer argumento a __new__
, todo en vano. ¿Por qué me está pateando tan duro? ¿Tengo que descubrir las metaclases de django para poder arreglar esto o hay una mejor manera de lograr mis objetivos?
Es tentador tratar de averiguar el rompecabezas, pero el instinto me dice que estás haciendo mal. Esto es como una tortura para el pobre ORM de Django. – keturn