Python django.db.models字段默认值未定义可调用

Python django.db.models字段默认值未定义可调用,python,django,python-3.x,django-models,Python,Django,Python 3.x,Django Models,我使用的是PyCharm 4.5.2和Django 1.8.2 如果我将类定义为: class User(models.Model): first_name = models.CharField(max_length=256) last_name = models.CharField(max_length=256) slug = models.SlugField(max_length=256, unique=True, default=make_slug) de

我使用的是PyCharm 4.5.2和Django 1.8.2

如果我将类定义为:

class User(models.Model):
    first_name = models.CharField(max_length=256)
    last_name = models.CharField(max_length=256)
    slug = models.SlugField(max_length=256, unique=True, default=make_slug)

    def make_slug(self):
        return self.first_name + self.last_name[0]
IDE突出显示
default=make_slug
,其中
make_slug
未定义。解释器同意,当开发服务器尝试刷新时,它退出状态为
1
,错误
namererror:name“make\u slug”未定义。

因为它只是一个可调用函数的名称,所以我不能传递参数。因此,如果我在类之外定义函数(移动到更高的范围并被定义),我就不能使用类属性。我已经阅读了一些使用lambdas的建议,但从中发现这是错误的:

请注意,lambdas不能用于像default这样的字段选项 因为它们不能通过迁移序列化。看到了吗 其他注意事项的文档


为模型中的默认值定义可调用值的正确方法是什么。

您不应该使用此方法设置默认值,而应该覆盖模型的save方法并在那里使用它。例如:

class User(models.Model):
    first_name = models.CharField(max_length=256)
    last_name = models.CharField(max_length=256)
    slug = models.SlugField(max_length=256, unique=True, default=uuid.uuid1)

    def make_slug(self):
        return self.first_name + self.last_name[0]

    def save(self, *args, **kwargs):
       self.slug = self.make_slug()
       super().save(*args, **kwargs)
你得到了这个错误

name错误:未定义名称“make\u slug”。

因为您在定义前参考了
make_slug
。如果将
make_slug
函数移到
slug
字段上方,则不会出现该错误

但是,不可能将任何参数传递给作为默认值使用的可调用对象,因此这也不起作用。您无法在尝试时使用模型方法来绕过该限制


如果需要访问模型实例来计算默认值,那么按照ruddra的建议,在
save()
方法中设置值是一个好主意。请注意,您可能希望检查模型是否有主键,以便仅在首次创建实例时创建slug。

尝试将
make\u slug
的定义移动到属性之前,即就在
first\u name=…
@Pynchia尝试了这一点之后,又出现了另一个问题。
makemigrations
migrate
任务可以工作,但是当我在“管理”面板中添加用户时,我得到一个
TypeError
make\u slug()缺少一个必需的位置参数:“self”
。从方法中删除
self
参数会否定类属性,并给出另一个
必须接受一个参数,通常是self
警告。好的。你得到了下面的答案。顺便问一下:你为什么要重新定义用户类?考虑使用一对一的关系,它使生活(至少对我来说)辛吉亚简单的回答:无知。目前我认为它可能有一个内置的用户管理系统,但因为我刚刚开始使用Django,所以我为一个简单的“CanImakeThisWork”测试构建了这个类。再次感谢你提供的链接,我明天会阅读它,可能会进行重构,因为这可能是更好的答案。感谢你的诚实。我自己也不是Django大师。尝试是最好的学习方法,我认为你走在了正确的轨道上。玩得开心!:)这是可行的,但是,文档表明我应该能够以这种方式使用callable。我希望得到一个能解决这个问题的答案,但如果几天后我没有得到答案,我会接受这个答案。谢谢,我不知道
uuid
。如果只是将slug字段添加到现有模型中,它也不起作用。迁移将要求一次性值。