2012-05-17 17 views
6

Tôi cần mở rộng người dùng django bằng một số trường bổ sung. Tôi tìm thấy 2 cách khác nhau cóTrường Ngoại khóa so với trường OneToOne django

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 
    #other fields 

HOẶC

class UserProfile(models.Model): 
    user = models.ForeignKey(User) 
    #other fields 

Chẳng phải họ giống nhau không? Sau khi đồng bộ hóa chúng, tôi thấy không có sự khác biệt trong cơ sở dữ liệu mysql

Trả lời

5

Không, tại sao bạn lại nghĩ vậy? ForeignKey là mối quan hệ một - nhiều - nghĩa là người dùng có thể có nhiều hồ sơ. OneToOne, như tên của nó, một mối quan hệ một-một - một người dùng chỉ có thể có một hồ sơ, mà âm thanh có nhiều khả năng hơn.

+0

Sau khi đồng bộ hóa, tôi thấy không có sự khác biệt trong cơ sở dữ liệu mysql, tôi đã hỏi cách phân biệt – sumit

+8

Sự khác biệt duy nhất * trong cơ sở dữ liệu * là một ràng buộc duy nhất trên cột với một-một. Thực tế, 'OneToOneField' chỉ đơn thuần là 'ForeignKey (unique = True)'. –

+1

Bạn sẽ không thấy bất kỳ sự khác biệt nào trong cơ sở dữ liệu của mình, vì syncdb không thay đổi bảng khi chúng được xác định, bạn sẽ cần phải thả và tạo lại chúng. Tuy nhiên, bạn có thể sử dụng 'sqlall' để hiển thị các kết quả đầu ra khác nhau - như Chris nói, OneToOne có một ràng buộc duy nhất. –

4

Như @Daniel Roseman cho biết, đây là 2 loại mối quan hệ rdbms khác nhau.

Bạn sẽ thấy rằng nó phân biệt trong trường hợp bạn sẽ có (do nhầm lẫn có thể) nhiều cấu hình cho một người dùng nhất định. Trong trường hợp đó, myuser.get_profile() sẽ tăng một ngoại lệ MultipleObjectsReturned, vì thực chất nó đang thực hiện truy vấn get(), bên dưới nắp.

+0

+1 Điểm tốt. Về mặt kỹ thuật, bạn có thể sử dụng ForeignKey, nhưng thiết lập nó như là một cách thích hợp để bảo vệ bạn khỏi chính mình bằng cách tăng một ngoại lệ nếu bạn cố tạo nhiều hơn một profile. –

+0

@ChrisPratt Có. Về cơ bản nếu bạn làm điều đó với một ForeignKey bạn đi chệch rất nhiều từ spec django (kể từ khi bạn làm cho get_profile vô dụng), rằng bạn tốt hơn bằng cách đặt tên cho mô hình mở rộng của bạn ngoài 'UserProfile'. – rantanplan

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