我在我的 models.py 文件中使用了以下代码:

创建指向外键的超链接

class ModelAdminWithForeignKeyLinksMetaclass(MediaDefiningClass):

    def __getattr__(cls, name):

        def foreign_key_link(instance, field):
            target = getattr(instance, field)
            return u'<a href="../../%s/%s/%s">%s</a>' % (
                target._meta.app_label, target._meta.module_name, target.id, unicode(target))

        if name[:8] == 'link_to_':
            method = partial(foreign_key_link, field=name[8:])
            method.__name__ = name[8:]
            method.allow_tags = True
            setattr(cls, name, method)
            return getattr(cls, name)
        raise AttributeError

在 admin.py list_display 中,我将 link_to 添加到我想要一个外键链接的每个字段的开头。这非常有效,但是当我关闭调试时,我收到一个属性错误。有什么建议么?

最佳答案

我偶然发现了完全相同的问题,幸运的是,我已经解决了。

原始解决方案(您使用的解决方案)来自 this question ,我的解决方案基于它:

class ForeignKeyLinksMetaclass(MediaDefiningClass):

    def __new__(cls, name, bases, attrs):

        new_class = super(
            ForeignKeyLinksMetaclass, cls).__new__(cls, name, bases, attrs)

        def foreign_key_link(instance, field):
            target = getattr(instance, field)
            return u'<a href="../../%s/%s/%d/">%s</a>' % (
                target._meta.app_label, target._meta.module_name,
                target.id, unicode(target)
            )

        for name in new_class.list_display:
            if name[:8] == 'link_to_':
                method = partial(foreign_key_link, field=name[8:])
                method.__name__ = name[8:]
                method.allow_tags = True
                setattr(new_class, name, method)

        return new_class

好吧,您唯一需要做的就是用上面的替换原来的 ModelAdminWithForeignKeyLinksMetaclass。

然而,这还不是结束。最有趣的部分是为什么原始解决方案会导致问题。这个问题的答案在于 o​​jit_a(第 31 行)和 here(第 244 行)。

当 DEBUG 在 Django 上时,它会尝试验证所有已注册的 ModelAdmins(第一个链接)。 cls 是一个 SomeAdmin(即它的元类的一个实例)。调用 hasattr 时,python 尝试在类 SomeAdmin 或其父类(super class)之一中查找属性字段。由于不可能,所以调用了它的类(即SomeAdmin的元类)的__getattr__,在类SomeAdmin中添加了一个新方法。因此,在渲染界面时,SomeAdmin 已经打好补丁,Django 能够找到所需的字段(第二个链接)。

当 DEBUG 为 False 时,Django 跳过验证。当界面呈现时,Django 尝试找到一个字段(再次,第二个链接),但这次 SomeAdmin 没有打补丁,而且 model_admin 不是类 SomeAdmin,它是 实例 。因此,试图在 model_admin 中查找属性名称,python 无法做到这一点,它既无法在其类 (SomeAdmin) 中也无法在其任何父类(super class)中找到它,因此引发了异常。

关于python - 当调试为 False 时,Admin 中的外键链接导致 AttributeError,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6473340/

10-10 08:49