Comme dans this question, sauf que je veux être en mesure d'avoir QuerySets qui retournent un corps mixte d'objets:modèles subclassed django avec QuerySets intégrés
>>> Product.objects.all()
[<SimpleProduct: ...>, <OtherProduct: ...>, <BlueProduct: ...>, ...]
je me suis dit que je ne peux pas mettre Product.Meta.abstract
true ou sinon juste OU ensemble des ensembles de différents objets. Bien, mais ce sont tous des sous-classes d'une classe commune, donc si je laisse leur superclasse comme non-abstraite, je devrais être heureux, tant que je peux obtenir que son manager retourne des objets de la classe appropriée. Le code de la requête dans django fait son truc, et fait juste des appels à Product(). Cela semble assez facile, sauf qu'il explose quand j'Override Product.__new__
, je devine à cause du __metaclass__
dans le modèle ... Voici le code non-django qui se comporte à peu près ce que je veux:
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>
Mais cela échoue si je hérité de django.db.models.Model
au lieu 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)
Ce qui est un backtrace notamment merdique; Je ne peux pas entrer dans le cadre de mon code __new__
dans le débogueur, soit. J'ai essayé diversement super(A, cls)
, Top
, super(A, A)
, et tout ce qui précède en combinaison avec le passage cls
en tant que premier argument à __new__
, le tout en vain. Pourquoi est-ce que ça me donne des coups de pied si durs? Est-ce que je dois comprendre les métaclasses de Django pour pouvoir résoudre ce problème ou existe-t-il un meilleur moyen d'atteindre mes objectifs?
Il est tentant d'essayer de comprendre le casse-tête, mais l'instinct me dit que vous faites fausse route. C'est comme une torture pour le pauvre petit ORM de Django. – keturn