Các tùy chọn mặc định của Django DateField


82

Tôi có một mô hình có trường thời gian ngày tháng:

date = models.DateField(_("Date"), default=datetime.now())

Khi tôi kiểm tra ứng dụng trong quản trị viên django được tích hợp sẵn, ứng dụng DateFieldnày cũng có thời gian được thêm vào ứng dụng đó, do đó nếu bạn cố gắng lưu nó, lỗi sẽ được trả về. Làm cách nào để đặt mặc định chỉ là ngày? ( datetime.today()cũng không hoạt động)

Câu trả lời:


150

Đây là lý do tại sao bạn nên luôn nhập cơ sở datetimemô-đun:import datetime , chứ không phải là datetimelớp trong mô-đun: from datetime import datetime.

Một sai lầm khác mà bạn đã thực hiện là thực sự gọi hàm theo mặc định, với (). Điều này có nghĩa là tất cả các mô hình sẽ có ngày tại thời điểm lớp được xác định lần đầu - vì vậy nếu máy chủ của bạn hoạt động trong nhiều ngày hoặc nhiều tuần mà không khởi động lại Apache, tất cả các phần tử sẽ có cùng ngày ban đầu.

Vì vậy, trường phải là:

import datetime
date = models.DateField(_("Date"), default=datetime.date.today)

Có cách nào để làm điều này thêm một delta thời gian không? Ví dụ: default = datetime.date.today + datetime.timedelta (days = 4) ... mã này không hoạt động, nhưng đó là ý tưởng. (Cấp, tiết kiệm phương pháp là một nơi để làm điều này, nhưng chỉ cần tự hỏi nếu có một cách để làm điều này như là một phần của định nghĩa)
Joe J

1
@Joe J: đây thực sự phải là một câu hỏi mới. Nhưng thực tế là bạn có thể sử dụng một hàm có thể gọi được có nghĩa là bạn chỉ có thể xác định hàm của riêng mình trả về ngày hôm nay + 4.
Daniel Roseman

23
Đang _("Date")làm gì vậy?
benregn

10
@benregn Nó đặt nhãn "Ngày" cho trường nhưng đánh dấu nó để dịch bằng cách sử dụng hệ thống quốc tế hóa.
Daniel Roseman

Cảm ơn vì đã làm rõ điều đó, tôi vừa mới bắt đầu phát triển Django và tôi hơi không rõ liệu nó có làm được nhiều hơn việc chỉ gắn nhãn hay không.
benregn

38

Sai lầm của bạn là sử dụng datetimemô-đun thay vì datemô-đun. Bạn muốn làm điều này:

from datetime import date
date = models.DateField(_("Date"), default=date.today)

Nếu bạn chỉ muốn ghi lại ngày hiện tại, cách thích hợp để xử lý điều này là sử dụng auto_now_addtham số:

date = models.DateField(_("Date"), auto_now_add=True)

Tuy nhiên, tài liệu trường mô hình nêu rõ rằng auto_now_addauto_nowsẽ luôn sử dụng ngày hiện tại và không phải là giá trị mặc định mà bạn có thể ghi đè.


8
date = models.DateTimeField(default=datetime.now, blank=True)

5
DateTimeField không giống nhau. Nếu bạn cung cấp ngày giờ làm mặc định cho DateField, bạn sẽ gặp rắc rối.
onekiloparsec

6

Tôi nghĩ rằng một cách tốt hơn để giải quyết vấn đề này là sử dụng datetime có thể gọi:

from datetime import datetime

date = models.DateField(default=datetime.now)

Lưu ý rằng không có dấu ngoặc đơn nào được sử dụng. Nếu bạn sử dụng dấu ngoặc đơn, bạn sẽ gọi now()hàm chỉ một lần (khi mô hình được tạo). Thay vào đó, bạn chuyển có thể gọi làm đối số, do đó được gọi mỗi khi một thể hiện của mô hình được tạo.

Tín dụng cho Django Musings . Tôi đã sử dụng nó và hoạt động tốt.


4

Cái này cần phải dùng mẹo:

models.DateTimeField(_("Date"), auto_now_add = True)

1
bạn của tôi, tôi nghĩ rằng bạn đã đọc nó sai. Câu hỏi là về DateField chứ không phải về DateTimeField.
xxbinxx

2

Bạn cũng có thể sử dụng lambda. Hữu ích nếu bạn đang sử dụng django.utils.timezone.now

date = models.DateField(_("Date"), default=lambda: now().date())

6
Nhìn vào tài liệu . Nó không phải là tốt để sử dụng lambda như mặc định Callable Wrapper: Note that lambdas cannot be used for field options like default because they cannot be serialized by migrations. See that documentation for other caveats.
pulina

@pulina bạn nói đúng, nhưng trong trường hợp này khi bạn cần cập nhật binded đến múi giờ cấu hình này trông giống như giải pháp duy nhất
oxfn

Không. Bạn có thể trỏ một chức năng thực tế trong mã. Bất kỳ tham chiếu chức năng hoặc phương pháp nào theo điều này liên quan đến chức năng cấp cao nhất của mô hình.
pulina
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.