在Python 3 / Django

时间:2017-11-25 02:20:50

标签: django python-3.x

我一直在查看参考资料和示例,但仍然无法做到这一点。

Django提供了许多使用元类作为工厂系统的一部分的示例,该工厂系统创建了特定于传入的值的各种方法等。这个想法很清楚。但它如何真正起作用有点神秘。

一段典型的Django(直接来自Django'入门'教程)代码如下所示:

from django.db import models

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


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

现在,稍后会有这些类的实际实例,例如:

q1 = Question(question_text='my question', pub_date='01-01-2017')

然而,对于全世界而言,在类定义中,question_text和pub_data看起来像是类范围的对象(即,由该类的所有实例共享,例如q1,q2等)。

更传统的做法和保持隔离的方法是在每个方面都有一个“自我”,以便类def看起来像:

class Question(models.Model):
    self.question_text = models.CharField(max_length=200)
    self.pub_date = models.DateTimeField('date published')

我甚至尝试查看Django的源代码。实际上,models.Model是一个类,它上面有一个元类,只要声明一个基于models.Model的新类,就会调用它。但代码相当神秘。

这里有什么惯用语吗?我假设在类中声明的变量并不是要跨实例共享。也许,我想,在那里声明变量(以及它们的类型,如果你愿意的话)只是一种将它们推入内部属性字典的方法,并且元类做了一些魔术来使事情发生导致某种结果这似乎更符合逻辑。

但是,不知何故,随着代码的出现,人们会创建另一个实例,如:

q2 = Question(question_text='my next question', pub_date='01-02-2017')

如果您引用q1.question_text或q2.pub_date,演示代码就可以正常运行,这样它们就像在类声明中声明的变量确实具有'self'一样。预先计划。

如果好奇,这里是Django源代码(Model位于第383行,上面是元类):https://github.com/django/django/blob/master/django/db/models/base.py

1 个答案:

答案 0 :(得分:2)

fields ,表示数据库模式中列的表示,是类级别的,但值是实例级别。

假设你有一个IntegerField:

class WithInt(models.Model):
    fld = models.IntegerField()

这意味着:

type(WithInt.fld) # IntegerField
inst = WithInt.objects.get(1)
type(inst.fld) # int