Para Django 1.1.
Tengo esto en mis models.py:
class User(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
Al actualizar una fila obtengo:
[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)
La parte relevante de mi base de datos es:
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
¿Es esto motivo de preocupación?
Pregunta secundaria: en mi herramienta de administración, esos dos campos no se muestran. ¿Es eso esperado?
python
django
datetime
django-models
django-admin
Paul Tarjan
fuente
fuente
update()
método no llamarásave()
lo que significa que no ha podido actualizarmodified
el campo automáticamenteRespuestas:
Cualquier campo con el
auto_now
conjunto de atributos también heredaráeditable=False
y, por lo tanto, no aparecerá en el panel de administración. Se ha hablado en el pasado sobre hacer que los argumentosauto_now
yauto_now_add
desaparezcan, y aunque todavía existen, creo que es mejor que solo use un método personalizadosave()
.Por lo tanto, para que esto funcione correctamente, recomendaría no usar
auto_now
oauto_now_add
y, en su lugar, definir su propiosave()
método para asegurarse de quecreated
solo se actualice siid
no está configurado (como cuando se creó el elemento por primera vez), y que se actualicemodified
cada vez que el elemento está guardadoHe hecho exactamente lo mismo con otros proyectos que he escrito usando Django, y así
save()
se vería así:¡Espero que esto ayude!
Editar en respuesta a los comentarios:
La razón por la que me quedo con la sobrecarga en lugar de
save()
depender de estos argumentos de campo es doble:django.utils.timezone.now()
vs.datetime.datetime.now()
, porque devolverá undatetime.datetime
objeto ingenuo o consciente de TZ dependiendo desettings.USE_TZ
.Para abordar por qué el OP vio el error, no sé exactamente, pero parece que
created
ni siquiera se está poblando, a pesar de haberlo hechoauto_now_add=True
. Para mí, se destaca como un error y subraya el elemento n. ° 1 en mi pequeña lista anterior:auto_now
yauto_now_add
en el mejor de los casos es escamoso.fuente
save()
en cada uno de mis modelos es mucho más difícil que usar elauto_now
(ya que me gusta tener estos campos en todos mis modelos). ¿Por qué no funcionan esos params?Pero quería señalar que la opinión expresada en la respuesta aceptada está algo desactualizada. De acuerdo con las discusiones más recientes (errores de django # 7634 y # 12785 ), auto_now y auto_now_add no irán a ninguna parte, e incluso si va a la discusión original , encontrará argumentos sólidos contra el RY (como en DRY) en el guardado personalizado métodos.
Se ha ofrecido una mejor solución (tipos de campo personalizados), pero no obtuvo el impulso suficiente para convertirse en django. Puedes escribir el tuyo en tres líneas (es la sugerencia de Jacob Kaplan-Moss ).
fuente
Hablando de una pregunta secundaria: si desea ver estos campos en admin (sin embargo, no podrá editarlo), puede agregar
readonly_fields
a su clase de administrador.Bueno, esto se aplica solo a las últimas versiones de Django (creo, 1.3 y superior)
fuente
XxAdmin
clase. Lo leí demasiado rápido e intenté agregarlo a mis clasesAdminForm
oModelForm
no tenía idea de por qué no mostraban los "campos de solo lectura". Por cierto, ¿existe la posibilidad de tener verdaderos "campos de solo lectura en un formulario?"Creo que la solución más fácil (y tal vez la más elegante) aquí es aprovechar el hecho de que puede establecer
default
una opción invocable. Entonces, para evitar el manejo especial del administrador de auto_now, puede declarar el campo de esta manera:Es importante que no lo use
timezone.now()
ya que el valor predeterminado no se actualizaría (es decir, el valor predeterminado se establece solo cuando se carga el código). Si te encuentras haciendo esto mucho, puedes crear un campo personalizado. Sin embargo, esto es bastante SECO ya creo.fuente
makemigrations
, interpreta el valor predeterminado como el momento en que lo ejecutamakemigrations
y, por lo tanto, piensa que el valor predeterminado ha cambiado.default=timezone.now()
lugar de lo que se recomienda:default=timezine.now
(sin paréntesis)?Si modifica su clase de modelo así:
Entonces este campo aparecerá en mi página de cambio de administrador
fuente
python manage.py makemigrations
: KeyError: u'editable 'Según lo que he leído y mi experiencia con Django hasta ahora, auto_now_add tiene errores. Estoy de acuerdo con jthanism --- anule el método normal de guardar, está limpio y sabe lo que está sucediendo. Ahora, para hacerlo seco, cree un modelo abstracto llamado TimeStamped:
Y luego, cuando desee un modelo que tenga este comportamiento de marca de tiempo, simplemente subclase:
Si desea que los campos se muestren en admin, simplemente elimine la
editable=False
opciónfuente
timezone.now()
estás usando aquí? Asumodjango.utils.timezone.now()
, pero no soy positivo. Además, ¿por qué usar entimezone.now()
lugar dedatetime.datetime.now()
?timezone.now()
es porque es consciente de la zona horaria, mientras quedatetime.datetime.now()
es ingenua. Puede leer sobre esto aquí: docs.djangoproject.com/en/dev/topics/i18n/timezonesdefault=timezone.now
dentro del constructor de campo?update_fields
se proporciona arg y 'last_modified' no está en la lista, agregaría:if 'update_fields' in kwargs and 'last_modifed' not in kwargs['update_fields']: kwargs['update_fields'].append('last_modified')
No, Django lo agrega automáticamente mientras guarda los modelos, por lo que se espera.
Como estos campos se agregan automáticamente, no se muestran.
Para agregar a lo anterior, como dijo synack, ha habido un debate sobre la lista de correo de django para eliminar esto, porque "no está bien diseñado" y es "un truco"
Obviamente no tienes que escribirlo en cada modelo. Puede escribirlo en un modelo y heredar otros de él.
Pero, como
auto_add
yauto_now_add
están allí, los usaría en lugar de tratar de escribir un método yo mismo.fuente
Necesitaba algo similar hoy en el trabajo. El valor predeterminado es
timezone.now()
, pero editable tanto en vistas de administrador como de clase heredadasFormMixin
, por lo que para mi creado,models.py
el siguiente código cumplía esos requisitos:Para
DateTimeField
, supongo que eliminar el.date()
de la función y cambiardatetime.date
adatetime.datetime
o mejortimezone.datetime
. No lo he probado conDateTime
, solo conDate
.fuente
Puede usar
timezone.now()
para creado yauto_now
para modificado:Si está utilizando una clave primaria personalizada en lugar de la predeterminada
auto- increment int
,auto_now_add
provocará un error.Aquí está el código del DateTimeField.pre_save predeterminado de Django con
auto_now
yauto_now_add
:No estoy seguro de cuál es el parámetro
add
. Espero que sea algo como:fuente
En cuanto a su pantalla de administrador, vea esta respuesta .
Nota:
auto_now
yauto_now_add
están configuradoseditable=False
de manera predeterminada, razón por la cual esto se aplica.fuente
auto_now=True
no funcionó para mí en Django 1.4.1, pero el siguiente código me salvó. Es para datetime consciente de la zona horaria.fuente
Aquí, hemos creado y actualizado columnas que tendrán una marca de tiempo cuando se creen y cuando alguien modifique los comentarios.
auto_now_add establecerá la hora cuando se crea una instancia, mientras que auto_now establecerá la hora en que alguien modificó sus comentarios.
fuente
Aquí está la respuesta si está usando South y desea establecer de manera predeterminada la fecha en que agrega el campo a la base de datos:
Elija la opción 2 y luego: datetime.datetime.now ()
Se ve como esto:
fuente