2009-08-04 12 views
7

Mam model django o nazwie Blog.Django: modele ostatnia data modyfikacji i liczba modów

Chciałbym dodać pole do mojego obecnego modelu, który jest dla last_modified_date. Wiem, jak ustawić wartość domyślną, ale chciałbym jakoś automatycznie zaktualizować go za każdym razem, gdy zmienię wpis w blogu za pośrednictwem interfejsu administratora.

Czy jest jakiś sposób na wymuszenie tej wartości do bieżącego czasu na każdej stronie administratora?

Czy byłby też jakiś sposób dodania pola mod_count i jego automatyczne obliczenie przy każdej modyfikacji wpisu blogu administratora?

Odpowiedz

12

Utwórz DateTimeField w swoim modelu. Miej go aktualizować po zapisaniu. Wymaga to, aby skorzystać z opcji auto_now_add:

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

DateTimeField.auto_now_add¶

Automatycznie ustawiane boiska i teraz za każdym razem, gdy obiekt zostanie zapisany. Przydatne dla "ostatnio modyfikowanych" znaczników czasu. Uwaga , że aktualna data jest zawsze używana; to nie tylko domyślna wartość, którą możesz zastąpić .

To powinno wyglądać mniej więcej tak:

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

Model field reference

Dla drugiej strony, myślę, że trzeba przeładowywać

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

James Bennett opisuje here. Będzie wyglądać mniej więcej tak:

class EntryAdmin(admin.ModelAdmin): 

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

dzięki, czy znasz sposób automatycznego zwiększania liczby o 1 przy każdym zapisie? –

+0

Tak, myślę, że musisz przeciążyć Model.save(), aby zrobić przyrost podczas składowania. James Bennett ma artykuł na ten temat na b-list.org, o ile pamiętam. Jego artykuł dotyczył zapisywania bieżącego użytkownika na zapisie w interfejsie administratora. Nie znalazłem jeszcze tego artykułu .... – hughdbrown

+0

Od co najmniej 1,4, "Przydatne dla" ostatnio zmodyfikowanych "znaczników czasu". notatka jest na 'auto_now' zamiast' auto_now_add'. Ten ostatni użyje tylko bieżącego czasu podczas tworzenia, a nie aktualizacji. –

2

Istnieje kilka sposobów na zwiększenie liczby edycji przy każdym zapisaniu.

Sam model ma metodę save(), a model admin ma metodę model_save().

Więc na przykład, powiedzmy, że chciał go zwiększyć, gdy został stworzony przy użyciu narzędzia administracyjnego ....

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

Można zrobić podobny kod off modelu save() zdarzenia, jak również.


Możesz być także zainteresowany numerem django-command-extensions. Dodaje 2 pola, które mogą być pomocne dla Ciebie:

  • CreationDateTimeField - DateTimeField który automatycznie ustawiony jest to data, kiedy obiekt jest najpierw zapisywane w bazie danych.

  • ModificationDateTimeField - DateTimeField, który automatycznie ustawi datę, kiedy obiekt zostanie zapisany w bazie danych.

+0

Czy możesz wskazać mi na dokumentacji, która mówi auto_now_add jest przestarzała? Niedawno 2008-06-15 odrzucono to stwierdzenie: "Nie wiem, kto jest anonimowy, ale auto_now_add nie zostało jeszcze przestarzałe. Mówiono o przestarzałości i istnieje lepszy sposób (domyślnie = datetime .now), ale na razie opcja auto_now_add jest nadal poprawną opcją. "http://code.djangoproject.com/ticket/7390 – hughdbrown

+0

Skopiowałem opis pola poza stronę projektu aplikacji django-extensions-extensions. Musiałbyś porozmawiać z nimi na temat tego stwierdzenia. –

+0

Aby nie propagować błędnych informacji * na wszelki wypadek *, usunąłem to z mojego wklejonego tekstu. –

0

Można również użyć rozwiązanie middleware znaleźć tutaj: 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

Zaakceptowanych odpowiedź nie jest poprawna.

W przypadku nowszych wersji django należy użyć parametru auto_now=True, a nie auto_now_add=True, który ustawi wartość pola tylko wtedy, gdy obiekt jest początkowo utworzony.

Z documentation:

DateField.auto_now_add¶

Automatycznie ustawić pole do teraz, gdy obiekt jest stworzony. Przydatny do tworzenia znaczników czasu.

Pożądana funkcjonalność jest obecnie realizowany przez auto_now:

DateField.auto_now¶

Automatycznie ustawiane boiska i teraz za każdym razem, gdy obiekt zapisany.

tak aby osiągnąć własny aktualizowanie znacznika czasu model powinien być tworzone tak:

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) 

Aby zwiększyć mod_count każdym razem model ten jest modyfikowany przeciążać modelu save() metody:

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