Django模型与Python类属性

9 投票
4 回答
3380 浏览
提问于 2025-04-15 23:07

在django网站上的教程里,展示了这样的代码来定义模型:

from django.db import models

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

class Choice(models.Model):
    poll = models.ForeignKey(Poll)
    choice = models.CharField(max_length=200)
    votes = models.IntegerField()

现在,这些属性都是类属性,对吧?也就是说,所有这个类的实例都应该共享同一个属性。稍后,他们又展示了这段代码:

class Poll(models.Model):
    # ...
    def __unicode__(self):
        return self.question

class Choice(models.Model):
    # ...
    def __unicode__(self):
        return self.choice

他们是怎么把类属性变成实例属性的呢?我是不是对类属性理解错了?

4 个回答

2

在Python中,类属性总是也是实例属性:

class C(object):
    a = 1
    def show_a(self):
        print self.a # <- works

但是在Django中,这个情况会更复杂,因为模型类有特殊的元类,所以要小心你的假设!

2

这是通过元类实现的,挺聪明的东西。如果你想了解更多,可以看看Marty Alchin写的《Pro Django》这本书,内容非常棒。

7

看看在 django/db/models.py 文件里的 Model 类。在那里,类的属性通过某种方式变成了实例的属性,像这样:

setattr(self, field.attname, val)

有人可能会推荐整个文件(ModelBaseModel 类)作为学习元类的一个很好的实际例子。

撰写回答