如何在不带微秒的情况下在Django中添加DateTimeField [英] How to add DateTimeField in django without microsecond

查看:139
本文介绍了如何在不带微秒的情况下在Django中添加DateTimeField的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在django 1.8和mysql 5.7中编写django应用程序.

I'm writing django application in django 1.8 and mysql 5.7.

下面是我编写的模型:

class People(models.Model):
    name = models.CharField(max_length=20)
    age = models.IntegerField()
    create_time = models.DateTimeField()

    class Meta:
        db_table = "people"

上述模型创建下表:

mysql> desc people;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | int(11)     | NO   | PRI | NULL    | auto_increment |
| name        | varchar(20) | NO   |     | NULL    |                |
| age         | int(11)     | NO   |     | NULL    |                | 
| create_time | datetime(6) | NO   |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+

此处Django创建的日期时间字段为微秒

Here Django creates datetime field with microsecond

datetime(6)

datetime(6)

但是我想要没有微秒的datetime字段

But I want datetime field without microsecond

日期时间

我有另一个应用程序,该应用程序也使用相同的数据库,而微妙的datetime字段对我来说是个问题.

I have another application, which is also using the same database and that datetime field with microsecond is raising an issue for me.

推荐答案

这确实是一个非常有趣的问题.我查看了源代码,这是用小数秒设置datetime的原因.以下代码片段来自文件django/db/backends/mysql/base.py:

This is really very interesting question. I looked through the source code and here is the reason for setting the datetime with fractional seconds. The following snippet is from the file django/db/backends/mysql/base.py:

class DatabaseWrapper(BaseDatabaseWrapper):
    vendor = 'mysql'
    # This dictionary maps Field objects to their associated MySQL column
    # types, as strings. Column-type strings can contain format strings; they'll
    # be interpolated against the values of Field.__dict__ before being output.
    # If a column type is set to None, it won't be included in the output.
    _data_types = {
        'AutoField': 'integer AUTO_INCREMENT',
        'BinaryField': 'longblob',
        'BooleanField': 'bool',
        'CharField': 'varchar(%(max_length)s)',
        'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
        'DateField': 'date',
        'DateTimeField': 'datetime',
        'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
        'DurationField': 'bigint',
        'FileField': 'varchar(%(max_length)s)',
        'FilePathField': 'varchar(%(max_length)s)',
        'FloatField': 'double precision',
        'IntegerField': 'integer',
        'BigIntegerField': 'bigint',
        'IPAddressField': 'char(15)',
        'GenericIPAddressField': 'char(39)',
        'NullBooleanField': 'bool',
        'OneToOneField': 'integer',
        'PositiveIntegerField': 'integer UNSIGNED',
        'PositiveSmallIntegerField': 'smallint UNSIGNED',
        'SlugField': 'varchar(%(max_length)s)',
        'SmallIntegerField': 'smallint',
        'TextField': 'longtext',
        'TimeField': 'time',
        'UUIDField': 'char(32)',
    }

    @cached_property
    def data_types(self):
        if self.features.supports_microsecond_precision:
            return dict(self._data_types, DateTimeField='datetime(6)', TimeField='time(6)')
        else:
            return self._data_types

    # ... further class methods

在方法data_types中,if条件检查MySQL版本.方法supports_microsecond_precision来自文件django/db/backends/mysql/features.py:

In the method data_types the if condition checks the MySQL version. The method supports_microsecond_precision comes from the file django/db/backends/mysql/features.py:

class DatabaseFeatures(BaseDatabaseFeatures):
    # ... properties and methods

    def supports_microsecond_precision(self):                                         
        # See https://github.com/farcepest/MySQLdb1/issues/24 for the reason          
        # about requiring MySQLdb 1.2.5                                               
        return self.connection.mysql_version >= (5, 6, 4) and Database.version_info >= (1, 2, 5)

因此,当您使用MySQL 5.6.4或更高版本时,字段DateTimeField会映射到datetime(6).

So when you use MySQL 5.6.4 or higher the field DateTimeField is mapped to datetime(6).

我找不到Django提供的任何调整方法,因此以猴子补丁结束了

I couldn't find any possibility given by Django to adjust this, so ended up with monkey patching:

from django.db.backends.mysql.base import DatabaseWrapper

DatabaseWrapper.data_types = DatabaseWrapper._data_types

将上面的代码放在最适合您需要的位置,例如models.py__init__.py,或者其他文件. 运行迁移时,即使您使用的是MySQL 5.7,Django也会为DateTimeField创建列datetime而不是datetime(6)列.

Put the above code where it suits best your needs, be it models.py or __init__.py, or maybe some other file. When running migrations Django will create column datetime and not datetime(6) for DateTimeField, even if you're using MySQL 5.7.

这篇关于如何在不带微秒的情况下在Django中添加DateTimeField的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆