Django: Al extender el usuario, mejor usar OneToOneField(usuario) o ForeignKey(usuario, único=verdadero)?
django foreign key (3)
Estoy encontrando información conflictiva sobre si usar OneToOneField (Usuario) o ForeignKey (Usuario, único = Verdadero) al crear un modelo de Perfil de Usuario extendiendo el modelo de Usuario de Django.
¿Es mejor usar esto ?:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
¿o esto?:
class UserProfile(models.Model):
user = models.OneToOneField(User)
El documento de Django especifica OneToOneField, mientras que el ejemplo de Django Book usa ForeignKey.
James Bennett también tiene dos publicaciones en el blog que proporcionan ejemplos contradictorios:
En la publicación anterior, Bennett proporciona algunas razones por las que cambió a usar ForeignKey en lugar de OneToOneField, pero no lo entiendo, especialmente cuando veo otras publicaciones que recomiendan lo contrario.
Tengo curiosidad por saber tu preferencia y por qué. ¿Ó acaso importa?
Además de las páginas de administración, otra razón para la solución ForeignKey
es que le permite usar el administrador de base de datos predeterminado correcto cuando se accede a los objetos con una relación inversa. Considere el ejemplo de este fragmento de administrador de subclases . Digamos que la definición de la clase Post
del ejemplo se ve así:
class Post(ParentModel):
title = models.CharField(max_length=50)
onetoone = models.ForeignKey(SomeModel, unique=True)
children = ChildManager()
objects = models.Manager()
Al llamar a somemodel_instance.post_set.all()[0]
, obtiene los objetos de las subclases deseadas de la clase Post
como se indica definiendo el primer administrador (predeterminado) como ChildManager
. Por otro lado, con OneToOneField
, al llamar a somemodel_instance.post
obtiene la instancia de la clase Post
. Siempre puede llamar a somemodel_instance.post.subclass_object
y obtener el mismo resultado, pero el administrador predeterminado podría hacer cualquier otro tipo de trucos y las soluciones FK
ocultan muy bien.
Si posee y puede modificar el código del administrador personalizado, puede usar el atributo use_for_related_fields
lugar de usar FK en lugar del campo 1to1 legítimo, pero incluso eso puede fallar debido a algunas molestias no conocidas por parte de los administradores automáticos. Por lo que recuerdo, fallará en el ejemplo anterior.
La única razón real que se da en el artículo es que se puede configurar para que la página de administración del User
muestre los campos en User
y User
de User
. Esto se puede replicar con OneToOneField
con un poco de OneToOneField
, así que a menos que seas adicto a mostrarlo en la página de administración sin trabajo a costa de un poco de claridad ("Podemos crear múltiples perfiles por usuario ?! Oh no , espera, es único. ") Utilizaría OneToOneField
.
Otra razón para no utilizar generalmente OneToOneField
relacionado con las relaciones inversas: cuando utiliza relaciones inversas definidas a través de OneToOneField
, obtiene una instancia de modelo, a diferencia de la relación inversa de Manager
for ForeignKey
y como consecuencia siempre hay un hit DB. Esto es costoso si usted hace algunas cosas genéricas en las relaciones inversas (a través de _meta.get_all_related_objects()
) y no sabe y le importa si las usará todas o no.