Selbstreferenzieller Fremdschlüssel von Django


165

Ich bin ein bisschen neu in Webapps und Datenbank-Sachen im Allgemeinen, also könnte dies eine dumme Frage sein. Ich möchte ein Modell ("CategoryModel") mit einem Feld erstellen, das auf die primäre ID einer anderen Instanz des Modells (seines übergeordneten Elements) verweist.

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

Wie mache ich das? Vielen Dank!


2
Stilistisch würde ich vorschlagen, dies parentanstelle von zu nennen parentId, da my_category_model.parentdies eine Instanz von sein wird CategoryModel. Django erstellt automatisch ein Mitglied, parent_iddas der Primärschlüssel des zugehörigen Modells ist.
10flow

Antworten:


262

Sie können den Namen eines Modells als Zeichenfolge an ForeignKey übergeben, und es wird das Richtige tun.

So:

parent = models.ForeignKey("CategoryModel")

Oder Sie können die Zeichenfolge "self" verwenden

parent = models.ForeignKey("self")

55

Sie können die Zeichenfolge 'self' verwenden, um eine Selbstreferenz anzugeben.

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

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


7
Ich denke du meinst 'Selbst'. Wie in der Zeichenfolge. Selbst ist in diesem Zusammenhang undefiniert
Jared Forsyth

1
@Brandon Wie unterscheidet sich "Selbst" in Ihrer Antwort von dem, was Jared in seinem Kommentar gesagt hat? "Ich denke du meinst 'Selbst" !!! . Beide sind Zeichenfolgen, die laut Django-Dokumenten in Ordnung sind. ! Irgendwelche Hinweise
Stryker

1
Der Unterschied besteht darin, dass selfbeim Definieren der Modelleigenschaft nicht vorhanden ist. Wenn die Eigenschaft als Teil der __init__()oder einer anderen Methode definiert würde, wäre dies wie selfimmer das erste Positionsargument für eine Instanzmethode einer Python-Klasse.
Brandon


1

Sie müssen auch null = True und blank = True festlegen

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

null = True, um in der Datenbank
blank zuzulassen = True, um die Formularvalidierung zuzulassen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.