Clave externa autorreferencial de Django


165

Soy un poco nuevo en aplicaciones web y bases de datos en general, por lo que esta podría ser una pregunta tonta. Quiero hacer un modelo ("CategoryModel") con un campo que apunte a la identificación primaria de otra instancia del modelo (su padre).

class CategoryModel(models.Model):
    parent = models.ForeignKey(CategoryModel)

¿Cómo hago esto? ¡Gracias!


2
Estilísticamente, sugeriría llamar a esto en parentlugar de parentId, ya my_category_model.parentque será una instancia de CategoryModel. Django creará automáticamente un miembro parent_idque será la clave principal del modelo relacionado.
10flow

Respuestas:


262

Puede pasar el nombre de un modelo como una cadena a ForeignKey y hará lo correcto.

Entonces:

parent = models.ForeignKey("CategoryModel")

O puedes usar la cadena "self"

parent = models.ForeignKey("self")

55

Puede usar la cadena 'self' para indicar una autorreferencia.

class CategoryModel(models.Model):
    parent = models.ForeignKey('self')

https://docs.djangoproject.com/en/dev/ref/models/fields/#foreignkey


77
Creo que te refieres a 'yo'. Como en la cuerda. yo no está definido en este contexto
Jared Forsyth

1
@Brandon ¿En qué se diferencia 'self' en tu respuesta de lo que dijo Jared en su comentario? "Creo que te refieres a ti mismo" !!! . Ambas son cadenas, lo cual está bien según los documentos de django. ! Cualquier pista
Stryker

1
La diferencia es que selfno está presente al definir la propiedad del modelo. Si la propiedad se definiera como parte del __init__()método u otro, lo sería, como selfsiempre es el primer argumento posicional de cualquier método de instancia de una clase Python.
Brandon


1

También debe establecer nulo = Verdadero y en blanco = Verdadero

class CategoryModel(models.Model):
    parent = models.ForeignKey("self", on_delete=models.CASCADE, null=True, blank=True)

null = True, para permitir en la base de datos
blank = True, para permitir la validación de formularios

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.