¿Cómo expresar una relación uno a muchos en Django?
Estoy definiendo mis modelos de Django en este momento y me di cuenta de que no había ningún OneToManyField
tipo de campo en el modelo. Estoy seguro de que hay una manera de hacer esto, así que no estoy seguro de lo que me estoy perdiendo. Básicamente tengo algo como esto:
class Dude(models.Model):
# 1 dude can have 0+ phone numbers
numbers = models.OneToManyField('PhoneNumber')
class PhoneNumber(models.Model):
number = models.CharField()
En este caso, cada uno Dude
puede tener múltiples PhoneNumber
s, pero la relación debe ser unidireccional, en el sentido de que no necesito saber quién PhoneNumber
lo Dude
posee, per se, ya que podría tener muchos objetos diferentes que posean PhoneNumber
instancias, como un Business
for ejemplo:
class Business(models.Model):
numbers = models.OneToManyField('PhoneNumber')
¿Con qué reemplazaría OneToManyField
(que no existe) en el modelo para representar este tipo de relación? Vengo de Hibernate/JPA donde declarar una relación de uno a muchos era tan fácil como:
@OneToMany
private List<PhoneNumber> phoneNumbers;
¿Cómo puedo expresar esto en Django?
Para manejar relaciones uno a muchos en Django necesitas usar ForeignKey
.
La documentación ForeignKey
es muy completa y debería responder a todas las preguntas que tenga:
https://docs.djangoproject.com/en/3.2/ref/models/fields/#foreignkey
La estructura actual en su ejemplo permite que cada uno Dude
tenga un número y que cada número pertenezca a varios Dude
s (lo mismo ocurre con Business
).
Si desea la relación inversa, deberá agregar dos ForeignKey
campos a su PhoneNumber
modelo, uno para Dude
y otro para Business
. Esto permitiría que cada número pertenezca a uno Dude
o uno Business
, y que Dude
sy Business
es pueda poseer múltiples PhoneNumber
s. Creo que esto podría ser lo que buscas:
class Business(models.Model):
...
class Dude(models.Model):
...
class PhoneNumber(models.Model):
dude = models.ForeignKey(Dude)
business = models.ForeignKey(Business)
En Django, una relación de uno a muchos se llama ForeignKey. Sin embargo, sólo funciona en una dirección, por lo que en lugar de tener un number
atributo de clase Dude
necesitarás
class Dude(models.Model):
...
class PhoneNumber(models.Model):
dude = models.ForeignKey(Dude)
Muchos modelos pueden tener un ForeignKey
a otro modelo, por lo que sería válido tener un segundo atributo de PhoneNumber
tal que
class Business(models.Model):
...
class Dude(models.Model):
...
class PhoneNumber(models.Model):
dude = models.ForeignKey(Dude)
business = models.ForeignKey(Business)
Puede acceder al PhoneNumber
s de un Dude
objeto d
con d.phonenumber_set.objects.all()
y luego hacer lo mismo con un Business
objeto.
Para ser más claro, no hay OneToMany en Django, solo ManyToOne, que es Foreignkey descrito anteriormente. Puede describir la relación OneToMany usando Foreignkey, pero eso es muy inexpresivo.
Un buen artículo al respecto: https://amir.rachum.com/blog/2013/06/15/a-case-for-a-onetomany-relationship-in-django/