django - relations - Diferencia entre ForeignKey(usuario, único=verdadero) y OneToOneField
one to one relations django (2)
Esta pregunta ya tiene una respuesta aquí:
¿Qué es diferente entre los models.ForeignKey(Modelname, unique=True)
y models.OneToOneField
en Django?
¿Dónde debería usar models.OneToOneField
y models.ForeignKey(Modelname, unique=True)
?
Un 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 los objetos relacionados.
En los documentos de Django dice:
Conceptualmente, esto es similar a una
ForeignKey
conunique=True
, pero el lado "inverso" 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 comienza con una persona, puede acceder a la dirección fácilmente:
address = person.address
Sin embargo, si comienza con una dirección, debe ir a través del administrador de la person_set
de la persona para obtenerla.
person = address.person_set.get() # may raise Person.DoesNotExist
Ahora reemplacemos la ForeignKey
con 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 comienza con una persona, puede acceder a la dirección de la misma manera:
address = person.address
Y ahora, podemos acceder a la persona desde la dirección más fácilmente.
person = address.person # may raise Person.DoesNotExist
Cuando accede a OneToOneField
obtiene el valor del campo que ha consultado. En este ejemplo, el campo ''título'' de un modelo de libro es OneToOneField
:
>>> from mysite.books.models import Book
>>> b = Book.objects.get(id=50)
>>> b.title
u''The Django Book''
Cuando accede a ForeignKey
obtiene el objeto de modelo relacionado, con el que puede preformar otras consultas. En este ejemplo, el campo ''publicador'' del mismo libro es una ForeignKey
(que se correlaciona con la definición del modelo de la clase Publisher
):
>>> b = Book.objects.get(id=50)
>>> b.publisher
<Publisher: Apress Publishing>
>>> b.publisher.website
u''http://www.apress.com/''
Las consultas de campos de ForeignKey
funcionan a la inversa, 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 escena, book_set es solo un QuerySet
y se puede filtrar y QuerySet
como cualquier otro QuerySet
. El nombre del atributo book_set se genera al _set
nombre del modelo en _set
a _set
. Espero que esto ayude a ilustrar las diferencias entre las relaciones creadas.