2009-08-04 18 views
7

Tengo un modelo django llamado Blog.Django: modelos última fecha de modificación y número de mod

Me gustaría agregar un campo a mi modelo actual que sea para last_modified_date. Sé cómo establecer un valor predeterminado, pero me gustaría de alguna manera que se actualice automáticamente en cualquier momento que modifique la entrada del blog a través de la interfaz de administración.

¿Hay alguna manera de forzar este valor a la hora actual en cada sitio de administración de guardar?

¿También habría alguna forma de agregar un campo mod_count y hacer que se calcule automáticamente en cada modificación de la entrada del blog del sitio de administración?

Respuesta

12

Cree DateTimeField en su modelo. Haga que se actualice cada vez que se guarde. Esto requiere el uso de la opción auto_now_add:

class DateTimeField([auto_now=False, auto_now_add=False, **options]) 

DateTimeField.auto_now_add¶

Se ajusta automáticamente el campo de ahora cada vez que el objeto se guarda. Útil para las marcas de tiempo "última modificación". Note que la fecha actual siempre se usa; no es solo un valor predeterminado que puede anular.

Debe ser algo como esto:

class Message(models.Model): 
    message = models.TextField() 
    active = models.BooleanField(default=True) 
    created_at = models.DateTimeField(auto_now_add=True) 

Model field reference

Para la segunda parte, yo creo que hay que sobrecargar

ModelAdmin.save_model(self, request, obj, form, change) 

Como James Bennett describe here. Se verá más o menos así:

class EntryAdmin(admin.ModelAdmin): 

def save_model(self, request, obj, form, change): 
    if change: 
     obj.change_count += 1 
    obj.save() 
+0

Gracias, ¿Conoces una manera de incrementar automáticamente un número en 1 en cada guardado? –

+0

Sí, creo que tiene que sobrecargar Model.save() para hacer el incremento durante el guardado. James Bennett tiene un artículo sobre esto en b-list.org, según recuerdo. Su artículo tenía que ver con guardar al usuario actual en un registro en la interfaz de administración. Todavía no he encontrado el artículo .... – hughdbrown

+0

Desde por lo menos 1.4, la 'Útil para' la última modificación '' timestamps ''. la nota está en 'auto_now' en lugar de' auto_now_add'. Este último solo usará la hora actual en crear, no actualizar. –

2

Hay varias maneras de aumentar el recuento de las ediciones cada vez que se guarda.

El modelo en sí tiene un método save() y el modelo admin tiene un método model_save().

Así, por ejemplo, digamos que quería que se incrementan cuando se editó con la herramienta de administración ....

models.py: 

class MyModel(models.Model): 
    edit_count = models.IntegerField() 
    # ... rest of model code here... 


admin.py: 

class MyModelAdmin(admin.ModelAdmin) 
    def save_model(self, request, obj, form, change): 
     if not change: 
      obj.edit_count = 1 
     else: 
      obj.edit_count += 1 
     obj.save() 

Usted podría hacer un código similar fuera del modelo, salvo caso() también.


Otra cosa que puede interesar es django-command-extensions. Se añade 2 campos que pueden ser útiles para usted:

  • CreationDateTimeField - DateTimeField que establecerá automáticamente que es la fecha en que el objeto se guarda primero en la base de datos.

  • ModificationDateTimeField - DateTimeField que establecerá automáticamente su fecha cuando se guarda un objeto en la base de datos.

+0

¿Puede indicarme la documentación que dice que auto_now_add está en desuso? Tan recientemente como el 15-06-2006, esta afirmación fue denegada: "No sé quién es anónimo, pero auto_now_add no ha sido desaprobado todavía. Se ha hablado de la desaprobación, y hay una forma mejor (predeterminado = fecha y hora) .now), pero por el momento, auto_now_add sigue siendo una opción válida. "http://code.djangoproject.com/ticket/7390 – hughdbrown

+0

He copiado la descripción del campo de la página de proyecto de la aplicación django-command-extensions. Tendría que hablar con ellos sobre esa afirmación. –

+0

Para no propagar información errónea * por las dudas *, la eliminé de mi texto pegado. –

0

También se puede utilizar una solución de middleware encontrado aquí: https://bitbucket.org/amenasse/django-current-user/src/7c3c90c8f5e854fedcb04479d912c1b9f6f2a5b9/current_user?at=default

settings.py

.... 
MIDDLEWARE_CLASSES = (
    .... 
    'current_user.middleware.CurrentUserMiddleware', 
    'current_user.middleware.CreateUserMiddleware', 
) 
.... 
INSTALLED_APPS = (
    'current_user', 
    .... 
    .... 
) 

models.py

class ExampleModel(models.Model): 
    foo = models.IntegerField() 
    last_user = CurrentUserField(related_name="+") 
    created_by = CreateUserField(related_name="+") 
5

La respuesta aceptada ya no es correcta.

Para las versiones django más nuevas, deberá usar el parámetro auto_now=True en lugar del auto_now_add=True, que solo establecerá el valor del campo cuando se cree inicialmente el objeto.

Desde el documentation:

DateField.auto_now_add¶

ajusta automáticamente el campo de ahora, cuando se creó por primera vez el objeto . Útil para la creación de marcas de tiempo.

La funcionalidad deseada ahora se implementa auto_now:

DateField.auto_now¶

Se ajusta automáticamente el campo de ahora cada vez que se guarda el objeto .

Así que para lograr la auto-actualización marcas de tiempo un modelo debe ser creado de esta manera:

class Message(models.Model): 
    message = models.TextField() 
    active = models.BooleanField(default=True) 
    created_at = models.DateTimeField(auto_now=True) 
    mod_count = models.IntegerField(default=0) 

Para incrementar mod_count cada vez que se modifica este modelo sobrecargue save() método del modelo:

def save(self, *args, **kwargs): 
     self.mod_count +=1 
     return super(Message,self).save(*args, **kwargs) 
Cuestiones relacionadas