2011-12-17 29 views
34

Dưới đây một số mô hình:Mô hình Django ForeignKey on_delete thuộc tính: đầy đủ ý nghĩa?

class UserProfile(models.Model): 
    name = models.CharField(max_length=30) 
    email = models.EmailField(unique=True, db_index=True) 
    birthday = models.DateField() 

class Photo(models.Model): 
    user = models.ForeignKey(UserProfile) 
    description = models.TextField(blank=True) 
    photo = models.ImageField(upload_to='img/photo') 

Hãy nói rằng người dùng có 10 ảnh (10 đối tượng Photo mô hình). Khi người dùng tự xóa mình, tất cả các hàng cơ sở dữ liệu 10 Photo sẽ tự động xóa chúng? (Tôi đã đọc tài liệu, nhưng tiếng Anh không phải là ngôn ngữ mẹ đẻ của tôi, vì vậy tôi không hiểu mọi thứ về thuộc tính on_delete.)

Trả lời

15

đó là hành vi mặc định, có. bạn có thể thay đổi hành vi này bằng on_delete

để xem minh họa điều này, hãy thử xóa một cấu hình người dùng trong quản trị viên. trước tiên nó hiển thị trang cảnh báo, liệt kê tất cả các đối tượng liên quan cũng sẽ bị xóa

+2

Ông liên kết cho 'on_delete' mình ... Tôi nghĩ rằng bạn đã không đọc bài đầy đủ của mình? –

+0

Tôi không muốn thay đổi hành vi này - tôi cần nó! Và điều gì xảy ra nếu xóa người dùng không phải từ pannel quản trị, nhưng dòng lệnh - hiệu ứng sẽ giống nhau? –

+1

có hiệu lực giống nhau. Tuy nhiên, lưu ý rằng theo mặc định, các tệp lưu trữ thực tế trong Photo.photo sẽ không * bị xóa – second

148

Tôi sẽ xem xét các giá trị cho on_delete khi chúng áp dụng cho trường hợp này. Vì ghi chú trong tài liệu, tất cả những điều này đều nằm trong mô-đun models đó, vì vậy bạn sẽ sử dụng nó như models.ForeignKey(UserProfile, on_delete=models.CASCADE), v.v.

Các quy tắc này được áp dụng tuy nhiên bạn xóa một đối tượng, cho dù bạn làm điều đó trong bảng quản trị hoặc làm việc trực tiếp với phiên bản Model. (Tuy nhiên, nó sẽ không có hiệu lực nếu bạn làm việc trực tiếp với cơ sở dữ liệu cơ bản trong SQL.)

  • CASCADE: khi bạn xóa các UserProfile, tất cả liên quan Photo s sẽ bị xóa quá. Đây là mặc định. (Vì vậy, trong câu trả lời cho rằng khía cạnh của câu hỏi của bạn, vâng, nếu bạn xóa người dùng tài khoản các bức ảnh sẽ bị xóa tự động.)

  • PROTECT: điều này sẽ ngăn chặn bạn xóa một UserProfile với liên quan Photo s, nuôi một django.db.models.ProtectedError nếu bạn thử. Ý tưởng sẽ là người dùng sẽ cần phải hủy liên kết hoặc xóa tất cả Photo trước khi họ có thể xóa hồ sơ của họ.

  • SET_NULL: khi bạn xóa các UserProfile, tất cả các liên Photo s sẽ vẫn còn tồn tại nhưng sẽ không còn được liên kết với bất kỳ UserProfile. Điều này sẽ yêu cầu null=True theo định nghĩa ForeignKey.

  • SET_DEFAULT: khi bạn xóa các UserProfile, tất cả các liên Photo s sẽ được thay đổi để trỏ đến mặc định của họ UserProfile theo quy định của default thuộc tính trong định nghĩa ForeignKey (bạn có thể sử dụng để vượt qua "mồ côi" ảnh giảm đến một người dùng nhất định - nhưng điều này sẽ không được phổ biến, SET_NULL hoặc SET() sẽ phổ biến hơn nhiều)

  • SET(): khi bạn xóa các UserProfile, mục tiêu của Photo s'ForeignKey sẽ được thiết lập với giá trị thông qua vào số SET chức năng, hoặc những gì nó trả về nếu nó là một cuộc gọi. (Xin lỗi, tôi đã không giải thích rằng tốt, nhưng docs có một ví dụ giải thích tốt hơn.)

  • DO_NOTHING: khi bạn xóa các UserProfile, tất cả liên quan Photo s sẽ vẫn không thay đổi gì, do đó có một tham chiếu bị hỏng, trừ khi bạn đã sử dụng một số SQL khác để chăm sóc nó.

(Ngoài ra, on_delete không phải là một phương pháp. Đó là một thuộc tính của trường ForeignKey.)

+1

Tôi đã thử CASCADE nhưng khi tôi xóa các hình ảnh UserProfile đã bị xóa và tôi đã cố gắng BẢO VỆ khi tôi đã cố gắng để xóa các hình ảnh nó nêu ra một lỗi. Tôi đã tự hỏi nếu đây là tác dụng phụ của thuộc tính on_delete ở đầu kia của mối quan hệ. Riêng đối với PROTECT, làm thế nào bạn có thể xóa tất cả các ảnh để bạn có thể xóa UserProfile nếu lỗi được bảo vệ được nâng lên? – Crystal

Các vấn đề liên quan