Chiave esterna autoreferenziale Django


166

Sono un po 'nuovo per le webapp e le cose del database in generale, quindi questa potrebbe essere una domanda stupida. Voglio creare un modello ("CategoryModel") con un campo che punta all'ID principale di un'altra istanza del modello (il suo genitore).

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

Come faccio a fare questo? Grazie!


2
Stilisticamente, suggerirei di chiamare questo parentinvece di parentId, poiché my_category_model.parentsarà un'istanza di CategoryModel. Django creerà automaticamente un membro parent_idche sarà la chiave primaria del modello correlato.
10flow

Risposte:


263

Puoi passare il nome di un modello come stringa a ForeignKey e farà la cosa giusta.

Così:

parent = models.ForeignKey("CategoryModel")

Oppure puoi usare la stringa "self"

parent = models.ForeignKey("self")

55

È possibile utilizzare la stringa 'self' per indicare un riferimento personale.

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

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


7
Penso che intendi "sé". Come nella stringa. il sé non è definito in questo contesto
Jared Forsyth

1
@Brandon In che modo 'sé' nella tua risposta è diverso da quello che Jared ha detto nel suo commento? "penso che intendi 'sé" !!! . Entrambi sono stringhe che vanno bene secondo i documenti di Django. ! Qualche suggerimento
Stryker,

1
La differenza è che selfnon è presente quando si definisce la proprietà del modello. Se la proprietà fosse definita come parte del __init__()o di un altro metodo, lo sarebbe, come selfsempre il primo argomento posizionale a qualsiasi metodo di istanza di una classe Python.
Brandon,


1

È inoltre necessario impostare null = True e blank = True

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

null = True, per consentire nel database
blank = True, per consentire la convalida del modulo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.