Django模型实例__nonzero__覆盖被忽略

时间:2013-10-09 13:22:47

标签: python django django-reversion

我正在尝试覆盖模型实例__nonzero__,因此评估为False

我首先在一个简单的Python类上测试过:

>>> class A():
...     pass
... 
>>> a = A()
>>> a.__nonzero__ = lambda: False
>>> b = A()
>>> bool(a)
False
>>> bool(b)
True
>>> type(a).__nonzero__(a)
False
>>> type(b).__nonzero__(b)
True

这表明被覆盖的__nonzero__成功改变了对象的bool()评估。

然后我尝试将相同的东西应用于django模型对象(feincms.module.page.Page的实例,它本身继承自`django.db.models.Manager)。

from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from feincms.module.page.modeladmins import PageAdmin
from feincms.module.page.models import Page
from guardian.admin import GuardedModelAdmin
from reversion import VersionAdmin


class PageAdmin(PageAdmin, GuardedModelAdmin, VersionAdmin):

    # some stuff
    # ...
    #

    def render_revision_form(self, *args, **kwargs): 
        """Override render_revision_form so we can make ``obj`` evaluate to False
        so ``feincms.module.page.forms.PageAdminForm.clean()`` does not try
        to query ``self.page_manager.get(pk=current_id)`` where current_id
        is ``obj.pk`` in the below function.
        This is needed because ``self.page_manager.get(pk=current_id)`` is
        queried on feincms Page objects rather than reversion Version objects.
        """
        request, obj, version, context = args
        obj.__nonzero__ = lambda: False
        obj.hello = 'a'
        import pdb
        pdb.set_trace()
        return super(PageAdmin, self).render_revision_form(request, obj, version, context, **kwargs)

admin.site.register(Page, PageAdmin)

但评估结果为True

(Pdb) obj
<Page: test>
(Pdb) bool(obj)
True

我有什么理由不知道这会导致这种行为吗?

1 个答案:

答案 0 :(得分:0)

在此示例中,您使用的是旧式类。而模型实例是一种新式的类。

class B(object): pass
b = B()
b.__nonzero__ = lambda: False
bool(b) # True

显然,您不能覆盖实例的特殊方法,仅适用于类型。

B.__nonzero__ = lambda self: False
bool(b) # False

阅读以下SO问题以获取示例和更详细的说明:"overriding-special-methods-on-an-instance"