在Django中保存模型给了我“警告:字段'id'没有默认值”

时间:2011-11-10 00:46:38

标签: python mysql django

我在Django中有一个非常基本的模型:

class Case(models.Model):
    name = models.CharField(max_length=255)
    created_at = models.DateTimeField(default=datetime.now)
    updated_at = models.DateTimeField(default=datetime.now)

    def save(self):
        if self.created_at == None:
             self.created_at = datetime.now()
        self.updated_at = datetime.now()
        super(Case, self).save()

    class Meta:
        db_table = u'cases'

因为我没有指定PK,所以Django为我处理了这个问题。我在我的数据库中看到了一个名为“id”的字段,标记为主键并自动增加。我觉得奇怪的是得到了警告,因为数据库和模型端的一切都很酷。错误是:

_mysql_exceptions.Warning

Warning: Field 'id' doesn't have a default value

我在保存时的工作是将id设置为0.它会终止警告并且无论如何都会正确设置id,因为MySQL处理它。

case = Case()
case.id = 0 #ugly workaround for - Warning: Field 'id' doesn't have a default value
case.name = request.POST[u'case[name]']
case.save()

此解决方案的问题是:

  1. 很难看
  2. 保存后,新PK无法访问 无法正确序列化
  3. 有谁知道如何解决这个问题?

    我正在跑步:

    Python 2.7.2
    django.VERSION (1, 3, 1, 'final', 0)
    mysql  Ver 14.14 Distrib 5.1.45, for apple-darwin10.2.0 (i386) using readline 5.1
    MySQL_python-1.2.3-py2.7-macosx-10.4-x86_64.egg
    

    我的create table看起来像这样:

    CREATE TABLE `cases` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) NOT NULL,
      `created_at` datetime NOT NULL,
      `updated_at` datetime NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM AUTO_INCREMENT=45 DEFAULT CHARSET=latin1
    

8 个答案:

答案 0 :(得分:13)

我想扩展这个问题,因为我本周遇到了这个问题。我得到了同样的错误,看看模型定义和SQL定义显​​示:

  1. 受影响的模型要么没有明确定义的PK,要么明确定义了PK(两者都有问题)。仅此一点似乎无关紧要。

  2. 受影响的表格具有OP中的“id”定义,即id int(11) NOT NULL AUTO_INCREMENTPRIMARY KEY按预期设置。

  3. 查看MySQL查询日志,我得到了一些东西:

    INSERT INTO `x` (...) VALUES (...)
    SHOW WARNINGS
    ROLLBACK
    

    单独运行查询是成功的,SHOW WARNINGS反映了OP中记录的警告。

  4. 但我遇到了一个MySQL端修复,http://webit.ca/2012/01/field-id-doesnt-have-a-default-value/提到重置id定义(粗略地看起来没有任何不同)修复了这个问题。我无法解释为什么这样可行,但它解决了这个问题而没有任何额外的代码更改。我相信这可能在某种程度上与删除记录有关,但整个问题对我来说似乎并不敏感。

答案 1 :(得分:5)

您是否有机会重新创建数据库?似乎它可能有问题。

作为旁注:如果您已将默认字段设置为datetime.now(),则无需为created_at致电datetime.now

答案 2 :(得分:2)

您的保存方法实际上没有必要,您可以使用参数:DateField.auto_nowDateField.auto_now_add。这些参数处理您的created_at和updated_at属性:

  1. DateField.auto_now:每次保存对象时自动将字段设置为现在。适用于“最后修改”的时间戳。
  2. DateField.auto_now_add:首次创建对象时自动将字段设置为now。用于创建时间戳。
  3. 再次尝试使用默认的save()方法,希望它有所帮助!

    有关auto_nowauto_now_add的更多信息:https://docs.djangoproject.com/en/dev/ref/models/fields/#datefield

答案 3 :(得分:1)

save方法有时会使用其他参数和关键字参数,但您无法处理它们。 我不确定,但这可能会解决您的问题

def save(self, *args, **kwargs):
    if self.created_at == None:
         self.created_at = datetime.now()
    self.updated_at = datetime.now()
    super(Case, self).save(*args, **kwargs)

答案 4 :(得分:1)

我通过过滤掉警告来解决这个问题:

import warnings
warnings.filterwarnings("ignore", "Field 'id' doesn't have a default value")

现在保存和序列化看起来不错

答案 5 :(得分:1)

我相信你现在可能已经解决了这个问题,但我遇到了同样的问题。

原来没有为主键设置自动增量,所以我通过为数据库中的每个主键启用自动增量来解决问题。

希望能帮助其他能够解决同样问题的人。

答案 6 :(得分:0)

我有同样的问题,当我查看mysql结构时,字段'id'不是第一个字段。我改变了结构,将它作为第一个字段的上诉,然后我的问题就解决了。但我仍然不知道它背后的真正问题。

解决该表的问题之前的SQL脚本: CREATE TABLE IF NOT NOT EXISTS marketing_sponseredhashtag(   user_id int(11)NOT NULL,   start_date datetime NOT NULL,   created datetime NOT NULL DEFAULT'2013-02-12 14:00:04',   modified datetime NOT NULL DEFAULT'2013-02-12 14:00:04',   payment十进制(10,2)NOT NULL,   paid tinyint(1)NOT NULL DEFAULT'0',   status tinyint(1)NOT NULL DEFAULT'0',   expiry_date datetime NOT NULL,    id int(11)NOT NULL AUTO_INCREMENT,   tag varchar(180)NOT NULL,   PRIMARY KEY(id),   KEY marketing_sponseredhashtag_403f60fuser_id) )ENGINE = MyISAM DEFAULT CHARSET = latin1 AUTO_INCREMENT = 4;

发布后修复了结构: CREATE TABLE IF NOT NOT EXISTS marketing_sponseredhashtag(    id int(11)NOT NULL AUTO_INCREMENT,   user_id int(11)NOT NULL,   start_date datetime NOT NULL,   created datetime NOT NULL DEFAULT'2013-02-12 14:00:04',   modified datetime NOT NULL DEFAULT'2013-02-12 14:00:04',   payment十进制(10,2)NOT NULL,   paid tinyint(1)NOT NULL DEFAULT'0',   status tinyint(1)NOT NULL DEFAULT'0',   expiry_date datetime NOT NULL,   tag varchar(180)NOT NULL,   PRIMARY KEY(id),   KEY marketing_sponseredhashtag_403f60fuser_id) )ENGINE = MyISAM DEFAULT CHARSET = latin1 AUTO_INCREMENT = 4;

答案 7 :(得分:0)

运行迁移时出现相同的错误,结果我不得不更改默认django表的结构: django_admin_log django_content_type django_migrations < / em>,因为主键设置不正确(我不知道为什么,也许在某个时候迁移不正确)

我使用以下查询来更新表:

ALTER TABLE django_migrations修改id INT(11)NOT NULL AUTO_INCREMENT;