Ngày tạo tự động cho các đối tượng mẫu Django?


153

Cách tốt nhất để tự động đặt ngày tạo cho một đối tượng và cũng là trường sẽ ghi lại khi đối tượng được cập nhật lần cuối?

mô hình:

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

lượt xem:

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

Tôi nhận được lỗi:

objects_object.created_at may not be NULL

Tôi có phải tự đặt giá trị này không? Tôi nghĩ rằng đó là điểm của các tham số được truyền tới DateTimeField(hoặc chúng chỉ là mặc định và vì tôi đã đặt editable=Falsenên chúng không được hiển thị trên biểu mẫu, do đó không được gửi trong yêu cầu và do đó không nhận được đưa vào mẫu?).

Cách tốt nhất để làm điều này là gì? Một __init__phương pháp?

Câu trả lời:


311

Bạn có thể sử dụng auto_nowauto_now_addcác tùy chọn cho updated_atcreated_attương ứng.

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

31
auto_nowauto_now_addđược coi là xấu xa, vì vậy hãy cố gắng tránh chúng. Câu trả lời này giải thích tại sao và cung cấp một cách tiếp cận tốt hơn, ghi đè save()phương thức.
gregoltsov

3
nó tạo ra lỗi này: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

1
xóa các hàng trên databas hoặc kiểm tra tùy chọn 1 và thêm timezone.now ()
mullerivan

Chọn một tùy chọn: 1 Vui lòng nhập giá trị mặc định ngay bây giờ, dưới dạng Python hợp lệ Các mô-đun datetime và django.utils.timezone có sẵn, do đó bạn có thể thực hiện, ví dụ: timezone.now () >>> timezone.now () Di chuyển cho 'aml_validations' :
mullerivan


26

Chà, câu trả lời trên là chính xác, auto_now_addauto_now sẽ làm điều đó, nhưng sẽ tốt hơn nếu tạo một lớp trừu tượng và sử dụng nó trong bất kỳ mô hình nào mà bạn yêu cầu created_atupdated_atcác trường.

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

    class Meta:
        abstract = True

Bây giờ bất cứ nơi nào bạn muốn sử dụng nó, bạn có thể thực hiện một kế thừa đơn giản và bạn có thể sử dụng dấu thời gian trong bất kỳ mô hình nào bạn thực hiện.

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

Theo cách này, bạn có thể tận dụng khả năng sử dụng lại hướng đối tượng, trong Django DRY (không lặp lại chính mình)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.