get_FIELD_display(在Django中)如何工作?

2024-05-23 20:04:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Django和Python的新手,最近在Django文档中遇到了很多方法,比如Model.get FOO_display()。“帮助”页说,可以用FOO替换字段的名称。我一直在试图弄清楚这在Python中是如何实现的,并研究了“Model”类的来源。 我偶然发现:

    def _get_FIELD_display(self, field):
        value = getattr(self, field.attname)
        return force_unicode(dict(field.flatchoices).get(value, value), strings_only=True)

我不明白在Python中如何可能: 1) 写这个

class Person(models.Model):
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
p = Person(name='John', gender='M')

p.get_gender_display()

那么,Python如何将FIELD(或FOO)改为gender呢?是某种Python的“邪恶”符号吗?(对不起,我不能问得更清楚)你能指一下Python手册页吗?

2)为什么Model类的source用前导下划线声明了_get_FIELD_display(),而上面提取的Python doc却没有下划线写“p.get_gender_display()”?再说一遍,你能给我一个Python手册页吗?


Tags: django文档selffieldgetmodelfoovalue
2条回答

类上的magic__getattr__方法可用于实现此类功能。__getattr__对于obj.attribute上不存在attribute的每个obj.attribute调用,并且实现可以返回它希望的任何内容。

这都是通过元类进行管理的—您将在源代码中看到,模型类定义了一个__metaclass__属性,该属性设置为ModelBase。元类对于类就像类对于实例一样。

因此,当Django类被定义为时调用元类。然后元类执行确定模型类属性的各种代码。因此,它遍历在模型类上声明的字段,并将每个字段作为实例属性进行赋值——这就是Django的声明性语法的工作原理。然后它调用每个字段的contribute_to_class方法,该方法向类本身添加任何字段特定的方法,其中一个方法是_get_FOO_display方法。你可以在django/db/models/fields/__init__.py中看到这个的源代码。

为了将_get_FIELD_display更改为get_myfieldname_display,它使用了一种称为“currying”的技术,这意味着它定义了一个新函数,该函数使用定义的参数应用原始方法-在本例中是字段的名称。

如果你对这些感兴趣的话,马蒂·阿尔钦的书《Pro Django》有一个很好的解释。

相关问题 更多 >