Tôi thấy tôi có thể ghi đè hoặc xác định pre_save, save, post_save
để làm những gì tôi muốn khi một phiên bản mẫu được lưu.khi nào sử dụng pre_save, lưu, post_save trong django?
Được ưu tiên nào trong tình huống nào và tại sao?
Tôi thấy tôi có thể ghi đè hoặc xác định pre_save, save, post_save
để làm những gì tôi muốn khi một phiên bản mẫu được lưu.khi nào sử dụng pre_save, lưu, post_save trong django?
Được ưu tiên nào trong tình huống nào và tại sao?
tôi sẽ cố gắng hết sức để giải thích nó với một ví dụ:
pre_save
và post_save
là signals được gửi bởi mô hình. Nói cách đơn giản hơn, các hành động cần thực hiện trước hoặc sau save
của mô hình được gọi.
Một save
triggers the following steps
Django cung cấp cách ghi đè các tín hiệu này.
Bây giờ,
pre_save
tín hiệu có thể được ghi đè cho một số xử lý trước khi thực tế lưu vào cơ sở dữ liệu sẽ xảy ra - Ví dụ: (Tôi không biết một ví dụ tốt về nơi pre_save
sẽ là lý tưởng ở phía trên đầu của tôi)
Cho phép nói rằng bạn có một ModelA
lưu trữ tham chiếu đến tất cả các đối tượng của ModelB
có chưa được chỉnh sửa. Đối với điều này, bạn có thể đăng ký một tín hiệu pre_save
để thông báo ModelA
ngay trước khi phương thức save
được gọi (Không có gì ngăn bạn đăng ký tín hiệu post_save
ở đây nữa).
Bây giờ, save
phương pháp (nó không phải là một tín hiệu) của mô hình được gọi là - Theo mặc định, tất cả các mô hình có một phương pháp save
, nhưng bạn có thể ghi đè lên nó:
class ModelB(models.Model):
def save(self):
#do some custom processing here: Example: convert Image resolution to a normalized value
super(ModelB, self).save()
Sau đó, bạn có thể đăng ký Tín hiệu post_save
(Điều này được sử dụng nhiều hơn là pre_save
)
Cách sử dụng chung là UserProfile
đối tượng được tạo trong hệ thống.
Bạn có thể đăng ký tín hiệu post_save
tạo một đối tượng UserProfile
tương ứng với mọi User
trong hệ thống.
Tín hiệu là cách giữ mọi thứ theo mô-đun và rõ ràng. (Thông báo rõ ràng ModelA
nếu tôi save
hoặc thay đổi một cái gì đó trong ModelB
)
Tôi sẽ nghĩ về các ví dụ về realworld cụ thể hơn để trả lời câu hỏi này tốt hơn. Trong khi đó, tôi hy vọng điều này sẽ giúp bạn
pre_save
nó được sử dụng trước khi giao dịch tiết kiệm.
post_save
nó được sử dụng sau khi giao dịch được lưu.
Bạn có thể sử dụng pre_save
ví dụ nếu bạn có một FileField
hoặc một ImageField
và xem nếu file
hoặc image
thực sự tồn tại.
Bạn có thể sử dụng post_save
khi có UserProfile
và bạn muốn tạo một cái mới tại thời điểm User
mới được tạo.
cho ví dụ 'pre_save' của bạn nơi bạn đưa ra ví dụ để kiểm tra xem tệp có tồn tại hay không, cái nào tốt hơn để sử dụng tín hiệu hoặc ghi đè phương thức lưu? bởi vì tôi đã có vấn đề để tăng lỗi cho biểu mẫu của tôi nếu tôi thêm xác thực trong tín hiệu 'pre_save' của tôi. –
@ Keda87 Nếu u r bằng cách sử dụng một hình thức tôi sẽ đi để ghi đè chức năng xác nhận của biểu mẫu. –
không! post_save thường được gọi trong một khối nguyên tử. Điều đó có nghĩa là post_save xảy ra * bên trong * giao dịch. – ashwoods
Đừng quên rủi ro khi tham gia. Nếu bạn sử dụng post_save phương pháp với instance.save() gọi, thay vì phương pháp .update, bạn nên ngắt kết nối của bạn post_save tín hiệu:
Signal.disconnect (receiver = Không, người gửi = None , dispatch_uid = None) [nguồn] Để ngắt kết nối bộ thu khỏi tín hiệu, gọi Signal.disconnect(). Các đối số được mô tả trong Signal.connect(). Phương thức trả về True nếu người nhận là bị ngắt kết nối và False nếu không.
Đối số người nhận cho biết người nhận đã đăng ký ngắt kết nối. Có thể là Không nếu dispatch_uid được sử dụng để nhận dạng người nhận.
... và kết nối lại sau.
cập nhật() phương pháp không gửi tín hiệu trước và sau_, lưu ý.
Cảm ơn câu trả lời chi tiết. Lý do tại sao 'post_save' được sử dụng cho việc tạo' UserProfile' là vì bạn có thể kiểm tra xem cá thể đó là 'created' hay không trong post_save? (Nhưng không phải trong pre_save, lưu) – eugene
Bạn có thể muốn thêm vào câu trả lời mà pre_save hoặc post_save có mỗi se không có gì để làm với các giao dịch. Nếu bạn sử dụng get_or_create hoặc yêu cầu giao dịch cấp, post_save sẽ xảy ra * bên trong * giao dịch, chứ không phải sau giao dịch đó. Tùy thuộc vào cơ sở dữ liệu bạn có thể sử dụng một số triển khai tín hiệu post_commit ngoài đó. – ashwoods