Last active
July 19, 2022 14:03
-
-
Save mateuspadua/50a843834a201bede1a0ab239d9fa877 to your computer and use it in GitHub Desktop.
Create a DateTimeField managed by MySQL and not by Django.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from datetime import datetime | |
from django.db.backends.mysql.base import DatabaseWrapper as MySQLDatabaseWrapper | |
class DBTimestampAutoNowField(models.DateTimeField): | |
""" | |
Cria um DateTimeField que é representado no banco de dados como um TIMESTAMP, | |
que é atualizado a cada modificação na instância, com a data atual com uma precisão | |
de milisegundos. | |
Essa atualização é gerenciada pelo próprio MySQL e não pelo Django, garantindo | |
assim a precisão do valor de cada atualização. | |
""" | |
def __init__(self, *args, **kwargs): | |
""" | |
Precisa ser null = False, para que o MySQL ao receber um valor None de um | |
.save() por exemplo, não salve NULL no banco, mas sim a data atual. | |
Ele faz isso sozinho se o campo for NOT NULL. | |
""" | |
kwargs["null"] = False | |
super().__init__(*args, **kwargs) | |
def db_type(self, connection): | |
if isinstance(connection, MySQLDatabaseWrapper): | |
return ( | |
"TIMESTAMP(6) NOT NULL default CURRENT_TIMESTAMP(6) " | |
"on update CURRENT_TIMESTAMP(6)" | |
) | |
return super().db_type(connection) | |
def get_db_prep_value(self, value, connection, prepared=False): | |
# É preciso passar para o banco de dados o valor None (NULL) para assim | |
# o MySQL entender que ele deve usar a data atual do server neste campo. | |
if isinstance(connection, MySQLDatabaseWrapper): | |
return None | |
# Usa uma data impossível para ter certeza que não estamos salvando nada de | |
# errado no banco quando for MySQL. | |
fixed_value = datetime(1900, 1, 1, 0, 0, 0) | |
return super().get_db_prep_value(fixed_value, connection, prepared) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment