2009-08-04 15 views
7

Ich habe ein Django-Modell namens Blog.Django: modelle letzte mod datum und mod count

Ich möchte meinem aktuellen Modell, das für last_modified_date steht, ein Feld hinzufügen. Ich weiß, wie man einen Standardwert einstellt, aber ich möchte irgendwie irgendwie automatisch aktualisiert werden, wenn ich den Blogeintrag über die Verwaltungsschnittstelle ändere.

Gibt es eine Möglichkeit, diesen Wert auf die aktuelle Zeit an jeder Admin-Site zu speichern?

Auch gibt es eine Möglichkeit, ein mod_count Feld hinzuzufügen und es automatisch bei jeder Änderung der Admin-Site Blog-Eintrag berechnet werden?

Antwort

12

Erstellen Sie eine DateTimeField in Ihrem Modell. Lassen Sie es aktualisieren, wenn es gespeichert wird. Dies erfordert, dass Sie die auto_now_add Option verwenden:

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

DateTimeField.auto_now_add¶

automatisch das Feld auf nun das Objekt jedes Mal gespeichert wird. Nützlich für "letzte-modifizierte" Zeitstempel. Hinweis , dass das aktuelle Datum immer verwendet wird; Es ist nicht nur ein Standardwert, den Sie überschreiben können.

Es sollte wie folgt aussehen:

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

Model field reference

Für den zweiten Teil, ich glaube, Sie

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

Als James Bennett beschreibt here zu überlasten haben. Es sieht ungefähr so ​​aus:

class EntryAdmin(admin.ModelAdmin): 

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

Danke, Weißt du, wie man eine Zahl bei jedem Speichern automatisch um 1 erhöht? –

+0

Ja, ich denke, Sie müssen die Model.save() überladen, um das Inkrement während des Speicherns zu tun. James Bennett hat einen Artikel dazu auf b-list.org, soweit ich mich erinnere. Sein Artikel hatte mit dem Speichern des aktuellen Benutzers in einem Datensatz in der Verwaltungsoberfläche zu tun. Ich habe den Artikel noch nicht gefunden .... – hughdbrown

+0

Seit mindestens 1.4, der "Nützlich für" zuletzt-modifizierte "Zeitstempel." Hinweis ist auf "auto_now" statt "auto_now_add". Letzterer verwendet nur die aktuelle Zeit beim Erstellen, nicht beim Aktualisieren. –

2

Es gibt eine Reihe von Möglichkeiten, wie Sie die Bearbeitungsanzahl jedes Mal erhöhen können, wenn es gespeichert wird.

Das Modell selbst hat eine save() -Methode, und das Admin-Modell hat eine model_save() -Methode.

So zum Beispiel, sagen wir, Sie es erhöhen wollte, wenn es mit dem Admin-Tool bearbeitet wurde ....

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() 

Sie ähnlichen Code tun konnte, als auch aus der Modell save() Ereignis.


etwas, was Du in interessiert sein django-command-extensions. Es fügt 2 Felder, die Ihnen nützlich sein können:

  • CreationDateTimeField - Datetimefield, dass es das Datum automatisch eingestellt wird, wenn das Objekt zuerst in der Datenbank gespeichert wird.

  • ModificationDateTimeField - DateTimeField, das automatisch sein Datum eingibt, wenn ein Objekt in der Datenbank gespeichert wird.

+0

Können Sie mich auf die Dokumentation verweisen, die besagt, dass auto_now_add veraltet ist? Noch bis zum 2008-06-15 wurde diese Behauptung abgelehnt: "Ich weiß nicht, wer anonym ist, aber auto_now_add ist noch nicht veraltet. Es wurde über das Veralten gesprochen, und es gibt einen besseren Weg (Standard = Datum/Uhrzeit) .now), aber für den Moment ist auto_now_add immer noch eine gültige Option. "http://code.djangoproject.com/ticket/7390 – hughdbrown

+0

Ich habe die Feldbeschreibung von der django-command-extensions App-Projektseite kopiert. Sie müssten mit ihnen über diese Behauptung sprechen. –

+0

Um falsche Informationen nicht weiterzugeben * nur für den Fall *, habe ich das aus meinem eingefügten Text entfernt. –

0

Sie können auch eine Middleware-Lösung hier verwenden: 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

Die akzeptierte Antwort ist nicht mehr korrekt.

Für neuere Django-Versionen müssen Sie den Parameter auto_now=True anstelle des auto_now_add=True verwenden, der den Feldwert nur beim Erstellen des Objekts festlegen wird.

Vom documentation:

DateField.auto_now_add¶

setzen automatisch das Feld jetzt, wenn das Objekt zunächst erstellt. Nützlich für die Erstellung von Zeitstempeln.

die gewünschte Funktionalität wird nun von auto_now implementiert:

DateField.auto_now¶

das Feld automatisch eingestellt jetzt jedesmal, wenn das Objekt gespeichert wird.

So selbst aktualisierende zu erreichen Zeitstempel ein Modell wie folgt erstellt werden soll:

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) 

dieses Modell zu erhöhen mod_count jedes Mal geändert wird, überlasten die save() Methode Modell:

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