为什么我不能将模型方法用作默认值? Python/Django 模型中的 self 是什么?

Why can't I use model methods as defaults? What is self in Python/Django models anyway?

我在理解 self 的行为时遇到了一个非常基本的问题。

具体来说,我不明白为什么以下两段代码都不起作用,第一个导致解释器抱怨

self is missing as an argument,

第二个

self couldn't be referenced.

class Model(models.Model)
    name = models.CharField(max_length=200)
    auto_gen_field = models.CharField(max_length=200, default=gen_field())

    def gen_field(self):
        return self.name + 'something'

class Model(models.Model)
    name = models.CharField(max_length=200)
    auto_gen_field = models.CharField(max_length=200, default=gen_field(self))

    def gen_field(self):
        return self.name + 'something'

以下代码也使用 self,工作正常:

class Model(models.Model)
    name = models.CHarField(max_length=200)
    auto_gen_field = models.CharField(max_length=200, blank=True)

    def gen_field(self):
        return self.name + 'something'

    def save(self):
        self.auto_gen_field = self.gen_field()
        super(Model, self).save(*args, **kwargs)

为什么 self 引用存在于一处而另一处不存在?

如何修复前两个片段?

您在声明字段时调用该方法。那时没有 self.

无论如何你都不想那样做。除了 self 的任何问题外,这样做会 return 静态默认值,因此所有实例都将使用相同的值。这就是为什么传递 callable 很重要:gen_field - 而不是结果 - gen_field().

(但请注意,这仍然行不通:实例不会传递给函数,因为它没有作为实例上的方法被调用。覆盖保存是可行的方法。)

self 按照惯例(它实际上是一个与其他任何名称一样的名称,重要的是它是 第一个参数 的 class 方法)一个 对 class 的当前实例的引用,或多或少类似于 C++ 中的 this/Java.

现在,在

class Model(models.Model)
    name = models.CharField(max_length=200)
    auto_gen_field = models.CharField(max_length=200, default=gen_field())

当计算 models.CharField(max_length=200, default=gen_field()) 时,没有 class 的实例 ,因此您不能在其中添加 self。 它没有也不可能有意义。

现在,来自:https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.Field.default

Field.default¶

The default value for the field. This can be a value or a callable object. If callable it will be called every time a new object is created.

The default cannot be a mutable object (model instance, list, set, etc.), as a reference to the same instance of that object would be used as the default value in all new model instances. Instead, wrap the desired default in a callable.

您想传递 callable - 这基本上类似于 function pointer.

的工作是:

def some_function():
     return something

...

auto_gen_field = models.CharField(max_length=200, default=some_function)

您可以 not,但是,使用像 gen_field() 这样的模型方法作为 default 因为 Django not 将模型实例作为提供的可调用对象的第一个参数传递。

您必须覆盖 save