我是Django和Python的新手,最近在Django文档中遇到了很多方法,比如Model.get_FOO_display().帮助页面说您可以用FOO替换字段的名称.我一直在试图弄清楚Python中的可能性,并研究了"模型"类源.在那里我遇到了这个:
def _get_FIELD_display(self, field):
value = getattr(self, field.attname)
return force_unicode(dict(field.flatchoices).get(value, value), strings_only=True)
Run Code Online (Sandbox Code Playgroud)
我无法理解在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()
Run Code Online (Sandbox Code Playgroud)
那么,Python如何将FIELD(或FOO)改为性别?它是某种Python'邪恶的'符号吗?(对不起,我不能问清楚)Coud你指向一些Python手册页?
2)为什么来自Model类的源使用前导下划线声明_get_FIELD_display(),但是上面的Python doc extract会在没有下划线的情况下写入"p.get_gender_display()"?再次,你能为此给出一个Python手册页吗?
Dan*_*man 24
这都是通过元类管理的 - 您将在源代码中看到Model类定义了一个__metaclass__
属性,该属性设置为ModelBase
.元类是作为类的一个实例.
因此,在定义 Django类时调用元类.然后,元类执行各种代码,这些代码确定模型类的属性.因此,它遍历模型类中声明的字段,并将每个字段分配为实例属性 - 这就是Django的声明性语法的工作原理.然后它调用每个字段的contribute_to_class
方法,该方法将任何特定于字段的方法添加到类本身 - 其中一个方法是_get_FOO_display
方法.你可以看到这个的来源django/db/models/fields/__init__.py
.
为了更改_get_FIELD_display
为get_myfieldname_display
,它使用一种称为"currying"的技术,这意味着它定义了一个新函数,该函数将原始方法应用于已定义的参数 - 在本例中为字段的名称.
如果你对这一切感兴趣,Marty Alchin的书Pro Django有一个很好的解释.
归档时间: |
|
查看次数: |
8034 次 |
最近记录: |