Saltar al contenido

Django auto_now y auto_now_add

La guía paso a paso o código que verás en este artículo es la solución más rápida y efectiva que hallamos a tu duda o problema.

Solución:

Cualquier campo con el auto_now attribute el conjunto también heredará editable=False y por lo tanto no aparecerá en el panel de administración. Se ha hablado en el pasado acerca de hacer la auto_now y auto_now_add los argumentos desaparecen, y aunque todavía existen, creo que es mejor usar solo un personalizado save() método.

Entonces, para que esto funcione correctamente, recomendaría no usar auto_now o auto_now_add y en su lugar define tu propio save() método para asegurarse de que created solo se actualiza si id no está configurado (como cuando el artículo se creó por primera vez) y haga que se actualice modified cada vez que se guarda el elemento.

He hecho exactamente lo mismo con otros proyectos que he escrito usando Django, por lo que tu save() se vería así:

from django.utils import timezone

class User(models.Model):
    created     = models.DateTimeField(editable=False)
    modified    = models.DateTimeField()

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.id:
            self.created = timezone.now()
        self.modified = timezone.now()
        return super(User, self).save(*args, **kwargs)

¡Espero que esto ayude!

Editar en respuesta a los comentarios:

La razón por la que me quedo con la sobrecarga save() vs. confiar en estos argumentos de campo es doble:

  1. Los altibajos antes mencionados con su fiabilidad. Estos argumentos dependen en gran medida de la forma en que cada tipo de base de datos con la que Django sabe cómo interactuar trata un campo de sello de fecha/hora, y parece romperse y/o cambiar entre cada versión. (Lo cual creo que es el ímpetu detrás de la llamada para eliminarlos por completo).
  2. El hecho de que solo funcionan en DateField, DateTimeField y TimeField, y al usar esta técnica puede completar automáticamente cualquier tipo de campo cada vez que se guarda un elemento.
  3. Usar django.utils.timezone.now() contra datetime.datetime.now()porque devolverá un TZ-aware o ingenuo datetime.datetime objeto dependiendo de settings.USE_TZ.

Para abordar por qué el OP vio el error, no lo sé exactamente, pero parece que created ni siquiera se está poblando en absoluto, a pesar de tener auto_now_add=True. Para mí, se destaca como un error y subraya el elemento n. ° 1 en mi pequeña lista anterior: auto_now y auto_now_add son escamosos en el mejor de los casos.

Pero quería señalar que la opinión expresada en la respuesta aceptada está algo desactualizada. De acuerdo con discusiones más recientes (errores de Django #7634 y #12785), auto_now y auto_now_add no van a ninguna parte, e incluso si vas a la discusión original, encontrarás argumentos sólidos en contra de RY (como en DRY) en el guardado personalizado. métodos.

Se ha ofrecido una mejor solución (tipos de campos personalizados), pero no ganó suficiente impulso para convertirlo en django. Puedes escribir el tuyo en tres líneas (es la sugerencia de Jacob Kaplan-Moss).

from django.db import models
from django.utils import timezone


class AutoDateTimeField(models.DateTimeField):
    def pre_save(self, model_instance, add):
        return timezone.now()

#usage
created_at = models.DateField(default=timezone.now)
updated_at = models.AutoDateTimeField(default=timezone.now)

Hablando de una pregunta secundaria: si desea ver estos campos en el administrador (aunque no podrá editarlo), puede agregar readonly_fields a su clase de administrador.

class SomeAdmin(ModelAdmin):
    readonly_fields = ("created","modified",)

Bueno, esto se aplica solo a las últimas versiones de Django (creo, 1.3 y superiores)

Tienes la posibilidad dar visibilidad a esta crónica si si solucionó tu problema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *