2012-03-30 12 views

Respuesta

38

A OneToOneField es muy similar a ForeignKey con unique=True. A menos que esté haciendo herencia de tablas múltiples, en cuyo caso debe usar OneToOneField, la única diferencia real es la API para acceder a objetos relacionados.

En el Django docs Dice:

Conceptualmente, esto es similar a un ForeignKey con unique=True, pero la "marcha atrás" lado de la relación devolverá directamente un solo objeto.

Vamos a mostrar lo que eso significa con un ejemplo. Considere dos modelos, Person y Address. Asumiremos que cada persona tiene una dirección única.

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) 

Si usted comienza con una persona, se puede acceder a la dirección fácil:

address = person.address 

Sin embargo, si usted comienza con una dirección, usted tiene que ir a través del gestor person_set llevar a la persona.

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

Ahora vamos a sustituir el ForeignKey con un 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) 

Si usted comienza con una persona, se puede acceder a la dirección de la misma manera:

address = person.address 

Y ahora, puede acceder a la persona de la dirección con mayor facilidad.

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

Creo que quiso decir "dirección = modelos.ForeignKey (dirección, único = verdadero)" en la clase Persona. – alan

+0

@alan - buena captura, arreglado ahora. – Alasdair

1

Cuando acceda a un OneToOneField se obtiene el valor del campo consultada. En este ejemplo el campo 'título' de un modelo de libro es un OneToOneField:

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

Cuando acceda a un ForeignKey que presentamos lo mejor modelo de objetos relacionados, que luego se puede preformas más consultas contra. En este ejemplo, el campo 'editor' el mismo del modelo de libro es un ForeignKey (en correlación con la definición del modelo Publisher clase):

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

Con ForeignKey procesa las consultas funcionan a la inversa también, pero son ligeramente diferentes debido a la naturaleza no simétrica de la relación.

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

Detrás de las escenas, book_set es sólo un QuerySet y se puede filtrar y rodajas como cualquier otro QuerySet. El nombre de atributo book_set se genera al agregar el nombre del modelo de minúscula al _set. Espero que esto ayude a ilustrar las diferencias entre las relaciones creadas.

Cuestiones relacionadas