Eu tenho o modelo db abaixo:
from datetime import datetime
class TermPayment(models.Model):
# I have excluded fields that are irrelevant to the question
date = models.DateTimeField(default=datetime.now(), blank=True)
Eu adiciono uma nova instância usando o abaixo:
tp = TermPayment.objects.create(**kwargs)
Meu problema: todos os registros no banco de dados têm o mesmo valor no campo data, que é a data do primeiro pagamento. Depois que o servidor reiniciar, um registro terá a nova data e os outros registros terão a mesma do primeiro. Parece que alguns dados estão em cache, mas não consigo encontrar onde.
banco de dados: mysql 5.1.25
django v1.1.1
default=datetime.now
- note, sem chamar comonow()
Não é o padrão para DateTimeField, mas ... útil em qualquer caso.Respostas:
parece que
datetime.now()
está sendo avaliado quando o modelo é definido, e não sempre que você adiciona um registro.O Django possui um recurso para realizar o que você já está tentando fazer:
ou
A diferença entre o segundo exemplo e o que você tem atualmente é a falta de parênteses. Ao passar
datetime.now
sem parênteses, você está passando a função real, que será chamada sempre que um registro for adicionado. Se você a passardatetime.now()
, estará apenas avaliando a função e passando o valor de retorno.Mais informações estão disponíveis na referência de campo do modelo do Django
fonte
expiry = models.DateTimeField(default=datetime.now + timedelta(days=30))
def now_plus_30(): return datetime.now() + timedelta(days = 30)
, e depois usarmodels.DateTimeField(default=now_plus_30)
default=lambda: datetime.now()+timedelta(days=30)
Em vez de usar,
datetime.now
você deve realmente usarfrom django.utils.timezone import now
Referência:
django.utils.timezone.now
então escolha algo assim:
fonte
auto_now_add
(que reconhece o fuso horário), poderá obter cálculos errados devido a diferenças errôneas de fuso horário.Na documentação no campo padrão do modelo django:
O valor padrão para o campo. Pode ser um valor ou um objeto que pode ser chamado. Se for chamado, será chamado toda vez que um novo objeto for criado.
Portanto, o seguinte deve funcionar:
fonte
default
( django-chinese-docs-14.readthedocs.io/en/latest/ref/models/... )David teve a resposta certa. O parêntese () faz com que o fuso horário chamado.now () seja chamado toda vez que o modelo for avaliado. Se você remover o () de timezone.now () (ou datetime.now (), se estiver usando o ingênuo objeto datetime) para torná-lo exatamente isso:
Depois, funcionará conforme o esperado:
novos objetos receberão a data atual quando eles forem criados, mas a data não será substituída toda vez que você gerenciar.py makemigrations / migrate.
Acabei de encontrar isso. Muito obrigado a David.
fonte
O
datetime.now()
é avaliado quando a classe é criada, não quando um novo registro está sendo adicionado ao banco de dados.Para alcançar o que você deseja, defina esse campo como:
Dessa forma, o
date
campo será definido para a data atual de cada novo registro.fonte
A resposta para esta aqui está realmente errada.
O preenchimento automático do valor (auto_now / auto_now_add não é o mesmo padrão). O valor padrão será realmente o que o usuário vê se for um objeto novo. O que eu normalmente faço é:
Certifique-se de que, se você está tentando representar isso em uma página de administrador, liste-o como 'read_only' e faça referência ao nome do campo
Novamente, faço isso porque meu valor padrão normalmente não é editável e as páginas de Admin ignoram os não editáveis, a menos que especificado de outra forma. Certamente, há uma diferença entre definir um valor padrão e implementar o auto_add, que é a chave aqui. Teste!
fonte
datetime.now()
está sendo avaliado uma vez, quando sua turma é instanciada. Tente remover os parênteses para que a funçãodatetime.now
seja retornada e depois avaliada. Eu tive o mesmo problema ao definir valores padrão para meusDateTimeField
e escrevi minha solução aqui .fonte
Na referência da linguagem Python, em Definições de função :
Felizmente, o Django tem uma maneira de fazer o que você deseja, se você usar o
auto_now
argumento paraDateTimeField
:Veja os documentos do Django para DateTimeField .
fonte
No Django 3.0
auto_now_add
parece funcionar comauto_now
reg_date=models.DateField(auto_now=True,blank=True)
fonte