Para o Django 1.1.
Eu tenho isso no meu models.py:
class User(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
Ao atualizar uma linha, recebo:
[Sun Nov 15 02:18:12 2009] [error] /home/ptarjan/projects/twitter-meme/django/db/backends/mysql/base.py:84: Warning: Column 'created' cannot be null
[Sun Nov 15 02:18:12 2009] [error] return self.cursor.execute(query, args)
A parte relevante do meu banco de dados é:
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
Isso é motivo de preocupação?
Pergunta secundária: na minha ferramenta de administração, esses dois campos não estão aparecendo. Isso é esperado?
python
django
datetime
django-models
django-admin
Paul Tarjan
fonte
fonte
update()
método não irá chamarsave()
o que significa que não foi possível atualizar omodified
campo automaticamenteRespostas:
Qualquer campo com o
auto_now
conjunto de atributos também será herdadoeditable=False
e, portanto, não será exibido no painel de administração. No passado, houve conversas sobreauto_now
comoauto_now_add
desaparecer os argumentos e , embora eles ainda existam, acho melhor você usar apenas um método personalizadosave()
.Portanto, para fazer isso funcionar corretamente, eu recomendaria não usar
auto_now
ou, emauto_now_add
vez disso, definir seu própriosave()
método para garantir quecreated
somente seja atualizado seid
não estiver definido (como quando o item é criado pela primeira vez) e que ele seja atualizadomodified
sempre que o item é salvo.Fiz exatamente a mesma coisa com outros projetos que escrevi usando o Django, e assim você
save()
ficaria assim:Espero que isto ajude!
Edite em resposta aos comentários:
A razão pela qual eu continuo sobrecarregando
save()
versus confiando nesses argumentos de campo é dupla:django.utils.timezone.now()
vs.datetime.datetime.now()
, pois retornará umdatetime.datetime
objeto sensível a TZ ou ingênuo, dependendosettings.USE_TZ
.Para resolver por que o OP viu o erro, não sei exatamente, mas parece que
created
nem sequer estou sendo preenchido, apesar de terauto_now_add=True
. Para mim, isso se destaca como um bug e ressalta o item 1 da minha pequena lista acima:auto_now
eauto_now_add
é, na melhor das hipóteses, esquisito.fonte
save()
em cada um dos meus modelos é muito mais trabalhoso do que usar oauto_now
(como eu gosto de ter esses campos em todos os meus modelos). Por que esses parâmetros não funcionam?Mas eu queria ressaltar que a opinião expressa na resposta aceita está um pouco desatualizada. De acordo com discussões mais recentes (erros do django # 7634 e # 12785 ), auto_now e auto_now_add não vão a lugar algum, e mesmo se você for para a discussão original , encontrará fortes argumentos contra o RY (como em DRY) no salvamento personalizado métodos.
Uma solução melhor foi oferecida (tipos de campos personalizados), mas não ganhou impulso suficiente para transformá-lo em django. Você pode escrever o seu em três linhas (é a sugestão de Jacob Kaplan-Moss ).
fonte
Falando sobre uma pergunta paralela: se você quiser ver esses campos em admin (você não poderá editá-lo), poderá adicionar
readonly_fields
à sua classe de administrador.Bem, isso se aplica apenas às versões mais recentes do Django (acredito, 1.3 e acima)
fonte
XxAdmin
classe. Eu o li muito rapidamente e tentei adicioná-lo às minhasAdminForm
ouModelForm
classes e não tinha ideia de por que eles não estavam processando os "campos somente leitura". BTW, há uma possibilidade de ter verdadeiros "somente leitura campos em um formulário?Acho que a solução mais fácil (e talvez a mais elegante) aqui é aproveitar o fato de que você pode definir
default
um valor que pode ser chamado. Portanto, para contornar o tratamento especial do auto_now pelo administrador, basta declarar o campo da seguinte forma:É importante que você não use,
timezone.now()
pois o valor padrão não será atualizado (ou seja, o padrão será definido apenas quando o código for carregado). Se você se encontra fazendo muito isso, pode criar um campo personalizado. No entanto, isso já é bastante SECO, eu acho.fonte
makemigrations
ele interpreta o padrão como o horário em que você executamakemigrations
e, portanto, pensa que o valor padrão foi alterado!default=timezone.now()
e não o que está sendo recomendado:default=timezine.now
(sem parênteses)?Se você alterar sua classe de modelo assim:
Em seguida, este campo será exibido na minha página de alteração de administrador
fonte
python manage.py makemigrations
: KeyError: u'editable 'Baseado no que li e na minha experiência com o Django até agora, o auto_now_add é um buggy. Concordo com o jthanism - substitua o método normal de salvamento, ele está limpo e você sabe o que está acontecendo. Agora, para torná-lo seco, crie um modelo abstrato chamado TimeStamped:
E então, quando você quiser um modelo que tenha esse comportamento de carimbo de hora, basta subclasse:
Se você deseja que os campos apareçam no administrador, remova a
editable=False
opçãofonte
timezone.now()
você está usando aqui? Estou assumindodjango.utils.timezone.now()
, mas não sou positivo. Além disso, por que usar emtimezone.now()
vez dedatetime.datetime.now()
?timezone.now()
é porque ele reconhece o fuso horário, enquantodatetime.datetime.now()
é ingênuo. Você pode ler sobre isso aqui: docs.djangoproject.com/en/dev/topics/i18n/timezonesdefault=timezone.now
dentro do construtor de campos?update_fields
arg é fornecido e 'last_modified' não está na lista, eu acrescentaria:if 'update_fields' in kwargs and 'last_modifed' not in kwargs['update_fields']: kwargs['update_fields'].append('last_modified')
Não, o Django o adiciona automaticamente ao salvar os modelos, portanto, é esperado.
Como esses campos são adicionados automaticamente, eles não são mostrados.
Para acrescentar ao exposto, como o synack disse, houve um debate na lista de discussão do django para removê-lo, porque "ele não foi bem projetado" e é "um hack"
Obviamente, você não precisa escrevê-lo em todos os modelos. Você pode gravá-lo em um modelo e herdar outros.
Mas, como
auto_add
eauto_now_add
existem, eu os usaria ao invés de tentar escrever um método.fonte
Eu precisava de algo semelhante hoje no trabalho. Valor padrão a ser
timezone.now()
, mas editável nas visualizações de administrador e de classe herdadas deFormMixin
, portanto, para criado no meumodels.py
código a seguir atendeu a esses requisitos:Para
DateTimeField
, eu acho que remover a.date()
partir da função e mudançadatetime.date
paradatetime.datetime
ou melhortimezone.datetime
. Eu não tentei comDateTime
, apenas comDate
.fonte
Você pode usar
timezone.now()
para criado eauto_now
para modificado:Se você estiver usando uma chave primária personalizada em vez da padrão
auto- increment int
, issoauto_now_add
causará um erro.Aqui está o código do DateTimeField.pre_save padrão do Django com
auto_now
eauto_now_add
:Não tenho certeza qual é o parâmetro
add
. Espero que seja algo como:fonte
Quanto à exibição do administrador, consulte esta resposta .
Nota:
auto_now
eauto_now_add
são definidos comoeditable=False
padrão, e é por isso que isso se aplica.fonte
auto_now=True
não funcionou para mim no Django 1.4.1, mas o código abaixo me salvou. É para data e hora com reconhecimento de fuso horário.fonte
Aqui, criamos e atualizamos colunas que terão um carimbo de data / hora quando criadas e quando alguém modificou o feedback.
auto_now_add definirá a hora em que uma instância será criada, enquanto auto_now definirá a hora em que alguém modificou seus comentários.
fonte
Aqui está a resposta se você estiver usando o sul e desejar usar como padrão a data em que você adicionar o campo ao banco de dados:
Escolha a opção 2 e: datetime.datetime.now ()
Se parece com isso:
fonte