Python 具有集成查询集的子类django模型
与中类似,但我希望能够拥有返回混合对象体的查询集:Python 具有集成查询集的子类django模型,python,django,django-models,django-queryset,metaclass,Python,Django,Django Models,Django Queryset,Metaclass,与中类似,但我希望能够拥有返回混合对象体的查询集: >>> Product.objects.all() [<SimpleProduct: ...>, <OtherProduct: ...>, <BlueProduct: ...>, ...] 但是如果我从django.db.models.Model而不是object继承,那就失败了: File "/home/martin/beehive/apps/hello_world/models.py"
>>> Product.objects.all()
[<SimpleProduct: ...>, <OtherProduct: ...>, <BlueProduct: ...>, ...]
但是如果我从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)
文件“/home/martin/beehive/apps/hello\u world/models.py”,第50行,在
A(0)
TypeError:必须以实例作为第一个参数调用未绑定的方法\uuuuu new\uuuuuu()(改为获取ModelBase实例)
这是一个非常糟糕的回溯;我也无法在调试器中进入我的\uuuuu new\uuuu
代码的框架。我尝试了各种各样的super(A,cls)
,Top
,super(A,A)
,以及以上所有方法,并将cls
作为\uuu new\uuuu
的第一个参数传入,但都没有效果。为什么这么用力踢我?我必须找出django的元类才能解决这个问题,还是有更好的方法来实现我的目标?好的,这很有效:
棘手的是这一点
class A(Top):
pass
def newA(cls, *args, **kwargs):
# [all that code you wrote for A.__new__]
A.__new__ = staticmethod(newA)
现在,关于Python如何绑定\uuuuu new\uuuuu
,我可能不太了解,但其要点是:django的ModelBase
元类创建一个新的类对象,而不是使用传递给它的\uuuuuuu new\uuuuuuuu
的对象;把它叫做素数。然后它将A
的类定义中的所有属性粘贴到A_prime
上,但是\uuu new\uu
没有正确地重新绑定
然后,当您计算A(1)
时,A
实际上是A_prime
这里,python调用(A_prime,1)
,它不匹配,然后爆炸
因此,解决方案是在定义了素数
之后定义你的\uuuuuu new\uuuuuu
也许这是django.db.models.base.ModelBase.add_to_class
中的一个bug,也许是Python中的一个bug,我不知道
现在,当我在前面提到“this works”时,我的意思是这与当前SVN版本的Django中的最小对象构造测试用例是隔离的。我不知道它是否真的可以作为一个模型使用,或者在QuerySet中是否有用。如果你真的在生产代码中使用了它,我会为pdxpython做一个公开的闪电演讲,让他们嘲笑你,直到你给我们买了所有的无麸质比萨饼。基本上你要做的是返回不同的子类,同时查询一个共享基类。也就是说:您需要叶类。检查此代码段以获取解决方案:
还要确保查看Django的Contenttypes框架上的文档:一开始可能会有点混乱,但Contenttypes将解决在Django的ORM中使用非抽象基类时可能会遇到的其他问题。只需在
\uuu new\uu
方法之前粘贴@staticmethod即可
@staticmethod
def __new__(cls, *args, **kwargs):
print args, kwargs
return super(License, cls).__new__(cls, *args, **kwargs)
您想要其中一个:
还有一些缺点,即额外的查询。我最近发现的另一种方法是:尝试解决这个难题很有诱惑力,但直觉告诉我你做错了。这对Django可怜的小ORM来说就像是一种折磨。好吧,这让我得到了所需的子类化行为,但它会打破我所有的关系吗!然后,我的任何对象都不能与其他模型关联。我将进一步研究它,看看是否可以修复该方面。snippet链接已断开。
@staticmethod
def __new__(cls, *args, **kwargs):
print args, kwargs
return super(License, cls).__new__(cls, *args, **kwargs)