Джанго самореференційний зовнішній ключ


165

Я взагалі новачок у веб-сайтах та базі даних загалом, тому це може бути тупим питанням. Я хочу зробити модель ("CategoryModel") з полем, яке вказує на первинний ідентифікатор іншого екземпляра моделі (її батьківського).

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

Як це зробити? Дякую!


2
Стилістично я б запропонував зателефонувати це parentзамість parentId, оскільки my_category_model.parentбуде екземпляром CategoryModel. Django автоматично створить член, parent_idякий буде первинним ключем пов'язаної моделі.
потоку

Відповіді:


262

Ви можете передати ім'я моделі як рядок до ForeignKey, і це зробить правильно.

Так:

parent = models.ForeignKey("CategoryModel")

Або ви можете використовувати рядок "self"

parent = models.ForeignKey("self")

55

Ви можете використовувати рядок "self", щоб вказати на самопосилання.

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

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


7
Я думаю, ти маєш на увазі «себе». Як у рядку. Я не визначений у цьому контексті
Джаред Форсайт

1
@Brandon Чим "я" у вашій відповіді відрізняється від того, що сказав Джаред у своєму коментарі? "Я думаю, ти маєш на увазі" себе "!!! . Обидва - це рядки, які добре відповідають документам про django. ! Будь-які підказки
Стрикер

1
Різниця полягає в тому, що selfпри визначенні властивості моделі немає. Якби властивість визначалося як частина того __init__()чи іншого методу, це було б, як selfзавжди, першим позиційним аргументом для будь-якого методу екземпляра класу Python.
Брендон


1

Ви також можете встановити null = True та blank = True

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

null = True, щоб дозволити в базі даних
blank = True, дозволити перевірку форми

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.