2012-04-03 128 views
8

我使用南迁移我的django模型。南部有一个令人讨厌的错误。它不会在Postgres数据库中设置默认值。例如:django南迁移,没有设置默认

created_at = models.DateTimeField(default = datetime.now) 
tag_id = models.PositiveIntegerField(default = 0) 

南会添加这些2场数据库,但未按规定设置的默认值,这需要手动完成。

是否有这个bug补丁的任何?

UPDATE 我已经尝试设置默认的日期与auto_now_add=True,但也没有设置默认值。在字段中添加null=True将在南部生成的迁移脚本中添加一个db.alter_column。但只有删除NOT NULL约束,不添加默认值。同为整数字段

回答

11

这是不是一个错误,在南方或其他地方。

我想你感到困惑的默认值在Django是如何工作的一般。 Django不会在数据库模式中设置默认值。当创建新实例时,它直接在Python中应用它们。您可以通过执行manage.py sqlall来验证这一点,并看到生成的SQL不包含default属性。

+2

如何在Postgres数据库中执行默认值。我有apis直接与django创建的数据库进行协商。他们预计违约将到位。 – jerrymouse 2012-04-03 11:12:24

+5

您必须使用自定义SQL来自己修改模式。您可以通过将SQL传递给['db.execute'](http://south.aeracode.org/docs/databaseapi.html#db-execute)在South内部执行此操作。 – 2012-04-03 11:46:59

+3

Daniel只是因为Django试图阻止用户在模式级别更改字段默认值,这并不意味着他们不应该能够。我已经发布了一个实际的解决方案。 – galarant 2013-01-22 03:20:38

21

如果您生成自动在您的迁移使用:

./manage.py schemamigration app_name --auto 

然后,你需要做一个小编辑到迁移之前,实际应用它。进入产生迁移(应该叫像APP_NAME /迁移/ 000X__auto_add_field_foo.py),并寻找论据:在db.add_column通话

keep_default=False 

。只需将其更改为:

keep_default=True 

除了任何现有行之外,Django现在将您的默认值应用于实际模式。如果South有某种设置来默认生成这个参数为True,但是没有这样的运气,那将会很棒。每次都需要进行编辑。

+0

+1比编写自定义SQL – 2013-03-28 17:50:11

+5

+1容易得多。不幸的是['keep_default'在南0.8.1中已弃用](http://south.readthedocs.org/en/latest/releasenotes/0.8.1.html#keep-default-fully-fully-deprecated) – Pankrat 2013-07-01 10:06:43

+0

该死的,Pankrat是对的... – galarant 2013-07-01 15:52:58

2

如前面的答案中提到,在Django默认的机制是在模型类中实现,而不是相关向南迁移。

此外,由于南0.8,the keep_default flag is deprecated,并不会默认值添加到您的模型。

我做些什么来解决这个问题是写一个自定义的迁移添加的默认值。你可以通过创建一个单独的data migration

./manage.py datamigration your_app_name migration_name 

和下面的行添加到forwards功能:

orm.YourModel.objects.update(field_name = DEFAULT_VALUE) 

或者,而不是创建一个新的迁移,您可以修改原来的迁移:

  1. no_dry_run = True添加到类本身(因此您将有权访问ORM)。
  2. orm.YourModel.objects.update(field_name = DEFAULT_VALUE)添加到forwards函数的末尾。

这样您就不必写回向迁移,因为您已经有了原始的删除列。