Fecha de creación automática para objetos de formulario de modelo Django

4 minutos de lectura

avatar de usuario
roger

¿Cuál es la mejor manera de establecer una fecha de creación para un objeto automáticamente y también un campo que registrará cuándo se actualizó por última vez el objeto?

modelos.py:

created_at = models.DateTimeField(False, True, editable=False)
updated_at = models.DateTimeField(True, True, editable=False)

vistas.py:

if request.method == 'POST':
    form = MyForm(request.POST)
    if form.is_valid():
        obj = form.save(commit=False)
        obj.user = request.user
        obj.save()
        return HttpResponseRedirect('obj_list')

me sale el error:

objects_object.created_at may not be NULL

¿Tengo que configurar manualmente este valor yo mismo? Pensé que ese era el punto de los parámetros pasados ​​​​a DateTimeField (o son solo valores predeterminados, y dado que configuré editable=False no se muestran en el formulario, por lo tanto, no se envían en la solicitud y, por lo tanto, ¿no se incluyen en el formulario?).

¿Cuál es la mejor manera de hacer esto? Un __init__ ¿método?

avatar de usuario
Manoj Govindan

Puedes usar el auto_now y auto_now_add opciones para updated_at y created_at respectivamente.

class MyModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

  • produce este error: You are trying to add a non-nullable field 'created_at' to gameuser without a default; we can't do that (the database needs something to populate existing rows). Please select a fix: 1) Provide a one-off default now (will be set on all existing rows) 2) Quit, and let me add a default in models.py Select an option: 1 Please enter the default value now, as valid Python The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now() >>> timezone.now()

    – Kaleem Ullah

    21 de junio de 2016 a las 10:56

  • elimine las filas en las bases de datos, o marque la opción 1 y agregue timezone.now()

    – mullerivan

    10 de marzo de 2017 a las 4:39

  • Django REST Framework parece pensar que este es un buen enfoque.

    – fénix

    25 de junio de 2019 a las 12:50

  • Creo que el comentario de @gregoltsov está desactualizado en este momento. Usando auto_now_add o auto_now funciona bien Establece el campo antes de guardar el modelo (github.com/django/django/blob/stable/3.0.x/django/db/models/…).

    – yndolok

    23 de julio de 2020 a las 20:34

  • Gracias @yndolok y Dandelion. ¡Eliminé mi comentario para que no confunda a las personas que llegan a esta respuesta!

    – gregoltsov

    20 de abril de 2021 a las 11:35

avatar de usuario
Chitrank Dixit

Bueno, la respuesta anterior es correcta, auto_ahora_añadir y auto_ahora lo haría, pero sería mejor hacer una clase abstracta y usarla en cualquier modelo donde lo requiera created_at y updated_at campos.

class TimeStampMixin(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

Ahora, en cualquier lugar que desee usarlo, puede hacer una herencia simple y puede usar la marca de tiempo en cualquier modelo que desee.

class Posts(TimeStampMixin):
    name = models.CharField(max_length=50)
    ...
    ...

De esta manera, puede aprovechar la reutilización orientada a objetos en Django DRY (no se repita)

  • Muy pronto te encuentras con 7 capas de herencia sin entender qué diablos está pasando… o mejor aún, 7 capas de herencia colapsadas en una sola clase con el nombre “Utilidad”.

    – arácnido

    18 de agosto de 2021 a las 14:58

  • @Spidey Estoy en conflicto con su comentario: por un lado, estoy muy de acuerdo en que el abuso de la abstracción (especialmente el con sabor a programación orientada a objetos) es más a menudo algo malo. Sin embargo, en este caso, me parece un caso de “buena (porque es predecible y generalmente útil) encapsulación de patrones/prácticas”, que es, cuando lo piensas, la esencia de marcos como Django y similares.

    – cjauvin

    27 de febrero a las 17:01


  • @cjauvin Entiendo tu posición, yo mismo he estado allí, pero honestamente creo que este ejemplo cae bajo composition over inheritance. Está bien inspirarse en libs/frameworks, pero recuerde que el código del proyecto no necesita ser tan reutilizable. Sin embargo, debe ser modificable rápidamente y agregar capas de herencia puede ser perjudicial en ese sentido.

    – arácnido

    27 de febrero a las 19:29

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad