Chave estrangeira auto-referencial do Django


165

Sou um pouco novo nos aplicativos da web e no banco de dados em geral, então essa pode ser uma pergunta idiota. Eu quero criar um modelo ("CategoryModel") com um campo que aponte para o ID primário de outra instância do modelo (seu pai).

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

Como eu faço isso? Obrigado!


2
Estilisticamente, eu sugeriria chamar isso em parentvez de parentId, já my_category_model.parentque será uma instância de CategoryModel. O Django criará automaticamente um membro parent_idque será a chave primária do modelo relacionado.
10flow

Respostas:


262

Você pode passar o nome de um modelo como uma sequência para ForeignKey e ele fará a coisa certa.

Assim:

parent = models.ForeignKey("CategoryModel")

Ou você pode usar a string "self"

parent = models.ForeignKey("self")

55

Você pode usar a string 'self' para indicar uma referência própria.

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

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


7
Eu acho que você quer dizer 'eu'. Como na corda. auto é indefinido neste contexto
Jared Forsyth

1
@Brandon Qual é a diferença entre 'self' em sua resposta e o que Jared disse em seu comentário? "Eu acho que você quer dizer 'eu" !!! . Ambos são strings, o que é bom, de acordo com os documentos do django. ! Qualquer dica #
Stryker

1
A diferença é que selfnão está presente ao definir a propriedade do modelo. Se a propriedade estivesse sendo definida como parte de um __init__()ou outro método, seria, como selfsempre, o primeiro argumento posicional para qualquer método de instância de uma classe Python.
Brandon


1

Você também deve definir null = True e em branco = True

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

null = True, para permitir no banco de dados em
branco = True, para permitir a validação do formulário

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.