2012-03-30 31 views

Trả lời

38

A OneToOneField rất giống với ForeignKey với unique=True. Trừ khi bạn đang làm nhiều thừa kế bảng, trong trường hợp này bạn phải sử dụng OneToOneField, sự khác biệt thực sự duy nhất là api để truy cập các đối tượng liên quan.

Trong Django docs nó nói:

Về mặt lý thuyết, điều này cũng tương tự như một ForeignKey với unique=True, nhưng "đảo ngược" bên của mối quan hệ sẽ trực tiếp trả về một đối tượng duy nhất.

Hãy hiển thị điều đó có nghĩa là với ví dụ. Cân nhắc hai mô hình, PersonAddress. Giả sử mỗi người có một địa chỉ duy nhất.

class Person(models.Model): 
    name = models.CharField(max_length=50) 
    address = models.ForeignKey('Address', unique=True) 

class Address(models.Model): 
    street = models.CharField(max_length=50) 

Nếu bạn bắt đầu với một người, bạn có thể truy cập vào địa chỉ một cách dễ dàng:

address = person.address 

Tuy nhiên, nếu bạn bắt đầu với một địa chỉ, bạn phải đi qua trình quản lý person_set để có được người đó.

person = address.person_set.get() # may raise Person.DoesNotExist 

Bây giờ hãy thay thế ForeignKey bằng OneToOneField.

class Person(models.Model): 
    name = models.CharField(max_length=50) 
    address = models.OneToOneField('Address') 

class Address(models.Model): 
    street = models.CharField(max_length=50) 

Nếu bạn bắt đầu với một người, bạn có thể truy cập vào địa chỉ trong cùng một cách:

address = person.address 

Và bây giờ, chúng ta có thể truy cập vào người từ địa chỉ dễ dàng hơn.

person = address.person # may raise Person.DoesNotExist 
+1

Tôi nghĩ bạn có nghĩa là "address = models.ForeignKey (Address, unique = True)" trong lớp Person. – alan

+0

@alan - bắt tốt, được khắc phục ngay bây giờ. – Alasdair

1

Khi bạn truy cập vào OneToOneField bạn nhận được giá trị của trường bạn truy vấn. Trong ví dụ này 'tiêu đề' lĩnh vực một mô hình cuốn sách là một OneToOneField:

>>> from mysite.books.models import Book 
>>> b = Book.objects.get(id=50) 
>>> b.title 
u'The Django Book' 

Khi bạn truy cập một ForeignKey bạn sẽ có được các đối tượng mô hình có liên quan, sau đó bạn có thể truy vấn phôi tiếp tục chống lại. Trong ví dụ này trường 'xuất bản' mô hình cuốn sách của cùng một ForeignKey (tương ứng với định nghĩa mô hình Publisher lớp):

>>> b = Book.objects.get(id=50) 
>>> b.publisher 
<Publisher: Apress Publishing> 
>>> b.publisher.website 
u'http://www.apress.com/' 

Với ForeignKey lĩnh vực truy vấn làm việc theo cách khác nữa, nhưng chúng hơi khác nhau do bản chất không đối xứng của mối quan hệ.

>>> p = Publisher.objects.get(name='Apress Publishing') 
>>> p.book_set.all() 
[<Book: The Django Book>, <Book: Dive Into Python>, ...] 

Đằng sau hậu trường, book_set chỉ là một QuerySet và có thể được lọc và cắt lát giống như bất kỳ QuerySet khác. Tên thuộc tính book_set được tạo bằng cách thêm tên mô hình chữ thường vào _set. Tôi hy vọng điều này sẽ giúp minh họa sự khác biệt giữa các mối quan hệ được tạo ra.

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