2013-07-15 32 views

Trả lời

20

tôi sẽ cố gắng hết sức để giải thích nó với một ví dụ:

pre_savepost_savesignals đượ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 savetriggers the following steps

  • Phát ra một tiền tiết kiệm tín hiệu.
  • Xử lý trước dữ liệu.
  • Hầu hết các trường không được xử lý trước - dữ liệu trường được giữ nguyên.
  • Chuẩn bị dữ liệu cho cơ sở dữ liệu.
  • Chèn dữ liệu vào cơ sở dữ liệu.
  • Phát ra tín hiệu sau khi lưu.

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 ModelBchư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

+0

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

+0

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

3
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.

+0

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. –

+0

@ 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. –

+0

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

1

Đừ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ác vấn đề liên quan