Django ORM,将没有日期时间作为0插入MySQL

时间:2014-01-27 13:34:36

标签: python mysql django

我有一个除了Django之外的其他应用程序使用的MySQL数据库。该应用程序使用'0000-00-00 00:00:00'作为日期时间的默认值。

Django(v1.5.5)在读取数据库时将'0000-00-00 00:00:00'日期时间解释为None,并在写入数据库时​​将None解释为NULL。这会导致错误,因为数据库将字段定义为NOT NULL

手动设定:

model.datetime = '0000-00-00 00:00:00'

不起作用,因为Django认为这是一个无效的日期。

如何创建自定义日期时间字段,将None作为'0000-00-00 00:00:00'插入?

3 个答案:

答案 0 :(得分:2)

创建自定义DateTimeField并覆盖get_db_prep_value。该方法是从django源复制的,并添加了一个案例来处理None。该值应以特定于数据库的方式进行转换,因此这有点hacky,但只要数据库接受0000-00-00 00:00:00作为日期时间,它就会起作用。

from django.db import models

class ZeroDateTimeField(models.DateTimeField):
    def get_db_prep_value(self, value, connection, prepared=False):
        # Casts datetimes into the format expected by the backend
        if not prepared:
            value = self.get_prep_value(value)

        # Use zeroed datetime instead of NULL
        if value is None:
            return  "0000-00-00 00:00:00"

        else:
            return connection.ops.value_to_db_datetime(value)
编辑:这个答案是为Django 1.5编写的,其他版本的支持尚未经过测试。

答案 1 :(得分:2)

基于Seppo的解决方案(由于缺少connection.ops.value_to_db_datetime而无法用于django 1.9.4),我最终使用了自定义DateTimeField,如下所示:

SQL> select * from product;

 NEW_PRICE  OLD_PRICE
---------- ----------
        34         25

SQL> update product set new_price = 30 where new_price = 34;

1 row updated.

SQL> commit;

Commit complete.

SQL> select * from product;

 NEW_PRICE  OLD_PRICE
---------- ----------
        30         34

SQL> 

然后在模型中使用ZeroDateTimeField而不是DateTimeField。

就像一个魅力,我不得不告诉客户修复他的mysql数据库; - )

编辑:我最终覆盖构造函数以设置null = True和blank = True以便于使用自动生成的模型。由于这可能对某些人有用,这里(这是可选的和可疑的):

from django.db import models

class ZeroDateTimeField(models.DateTimeField):
    def get_db_prep_value(self, value, connection, prepared=False):
        value = super( ZeroDateTimeField, self ).get_db_prep_value( value, connection, prepared )
        if value is None:
            return  "0000-00-00 00:00:00"
        return value

答案 2 :(得分:0)

添加default parameter to the datetime field时会发生什么?

my_date = fields.DateTimeField(default=0)

我认为如果MySQL接受它,Django也应该接受它。