为什么我不能将模型方法用作默认值? 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
。
我在理解 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
。