2009-08-04 37 views
7

Tôi có một mô hình django được gọi là Blog.Django: mô hình ngày mod cuối cùng và số mod

Tôi muốn thêm trường vào mô hình hiện tại của mình là dành cho last_modified_date. Tôi biết làm thế nào để thiết lập một giá trị mặc định, nhưng tôi muốn bằng cách nào đó cho nó để có được tự động cập nhật bất cứ lúc nào tôi sửa đổi các mục blog thông qua giao diện quản trị.

Có cách nào để buộc giá trị này đến thời điểm hiện tại trên mỗi trang web quản trị lưu không?

Cũng sẽ có cách nào đó để thêm trường mod_count và tự động tính toán trên mỗi sửa đổi của mục nhập blog của trang quản trị?

Trả lời

12

Tạo một DateTimeField trong mô hình của bạn. Cập nhật nó bất cứ khi nào nó được lưu. Điều này đòi hỏi bạn phải sử dụng các tùy chọn auto_now_add:

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

DateTimeField.auto_now_add¶

Tự động thiết lập các lĩnh vực đến nay mỗi khi đối tượng được lưu. Hữu ích cho dấu thời gian "được sửa đổi lần cuối". Lưu ý rằng ngày hiện tại luôn được sử dụng; không chỉ là giá trị mặc định mà bạn có thể ghi đè.

Nó sẽ giống như thế này:

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

Model field reference

Đối với phần thứ hai, tôi nghĩ rằng bạn cần phải quá tải

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

Như James Bennett mô tả here. Nó sẽ trông giống như sau:

class EntryAdmin(admin.ModelAdmin): 

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

Cảm ơn, bạn có biết cách tự động tăng số 1 lên mỗi lần lưu không? –

+0

Vâng, tôi nghĩ rằng bạn phải quá tải Model.save() để làm tăng trong quá trình lưu. James Bennett có một bài viết về điều này tại b-list.org, như tôi nhớ lại. Bài viết của ông đã làm với việc lưu người dùng hiện tại trên một bản ghi trong giao diện quản trị. Tôi chưa tìm thấy bài viết nào .... – hughdbrown

+0

Vì ít nhất 1.4, dấu thời gian "hữu ích cho" được sửa đổi lần cuối ". lưu ý là trên 'auto_now' thay vì' auto_now_add'. Sau này sẽ chỉ sử dụng thời gian hiện tại khi tạo, không cập nhật. –

2

Có một số cách bạn có thể tăng số lần chỉnh sửa mỗi lần lưu.

Bản thân mô hình có phương thức save() và mô hình quản trị có phương thức model_save().

Vì vậy, ví dụ, giả sử bạn muốn nó tăng khi nó đã được chỉnh sửa với công cụ quản trị ....

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

Bạn có thể làm tương tự như mã tắt của các mô hình tiết kiệm() sự kiện là tốt.


Điều gì đó bạn có thể quan tâm là django-command-extensions. Nó cho biết thêm 2 lĩnh vực mà có thể hữu ích cho bạn:

  • CreationDateTimeField - DateTimeField đó sẽ tự động thiết lập đó là ngày khi đối tượng đầu tiên được lưu vào cơ sở dữ liệu.

  • ModificationDateTimeField - DateTimeField sẽ tự động đặt ngày đó khi đối tượng được lưu vào cơ sở dữ liệu.

+0

Bạn có thể chỉ cho tôi tài liệu nói rằng auto_now_add không còn được dùng nữa? Gần đây nhất là 2008-06-15, xác nhận này đã bị từ chối: "Tôi không biết ai ẩn danh, nhưng auto_now_add vẫn chưa được phản đối. Đã có cuộc trò chuyện về việc không dùng nữa và có cách tốt hơn (mặc định = datetime .now), nhưng hiện tại, auto_now_add vẫn là một tùy chọn hợp lệ. "http://code.djangoproject.com/ticket/7390 – hughdbrown

+0

Tôi đã sao chép mô tả trường khỏi trang dự án ứng dụng django-command-extensions. Bạn sẽ phải nói chuyện với họ về sự khẳng định đó. –

+0

Để không truyền bá thông tin sai lệch * chỉ trong trường hợp *, tôi đã xóa thông tin đó khỏi văn bản đã dán của mình. –

0

Bạn cũng có thể sử dụng một giải pháp trung tìm thấy ở đây: 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

Câu trả lời được chấp nhận là không còn chính xác.

Đối với phiên bản django mới hơn, bạn sẽ phải sử dụng thông số auto_now=True thay vì auto_now_add=True, sẽ chỉ đặt giá trị trường khi đối tượng được tạo ban đầu.

Từ documentation:

DateField.auto_now_add¶

Tự động thiết lập hiện trường để bây giờ khi đối tượng là lần đầu tiên tạo ra. Hữu ích cho việc tạo dấu thời gian.

Các chức năng mong muốn hiện nay được thực hiện bởi auto_now:

DateField.auto_now¶

Tự động thiết lập các lĩnh vực đến nay mỗi khi đối tượng được lưu.

Vì vậy, để đạt được tự động cập nhật timestamps một mô hình cần được tạo ra như thế này:

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) 

Để tăng mod_count mọi mô hình này được sửa đổi quá tải phương pháp save() của mô hình:

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