Самореферентный внешний ключ Django

166

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

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

Как мне это сделать? Спасибо!

sfendell
источник
2
В стилистическом плане я бы предложил называть это parentвместо parentId, так как my_category_model.parentэто будет экземпляр CategoryModel. Django автоматически создаст элемент, parent_idкоторый будет основным ключом связанной модели.
ое

Ответы:

263

Вы можете передать имя модели в виде строки в ForeignKey, и она будет работать правильно.

Так:

parent = models.ForeignKey("CategoryModel")

Или вы можете использовать строку "себя"

parent = models.ForeignKey("self")
Джаред Форсайт
источник
55

Вы можете использовать строку «self» для указания собственной ссылки.

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

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

Brandon
источник
7
Я думаю, что вы имеете в виду «я». Как в строке. Я не определен в этом контексте
Джаред Форсайт
1
@ Брэндон Чем «я» в вашем ответе отличается от того, что сказал Джаред в своем комментарии? «Я думаю, что вы имеете в виду« я »!!! , Обе строки, что хорошо в соответствии с Django Docs. ! Любые намеки
Stryker
1
Разница в том, что selfнет при определении свойства модели. Если бы свойство определялось как часть __init__()или другого метода, оно было бы, как selfи всегда, первым позиционным аргументом для любого метода экземпляра класса Python.
Брэндон
1

Вы также должны установить NULL = True и пусто = True

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

null = True, чтобы разрешить в базе данных
пусто = True, чтобы разрешить в проверке формы

Punnerud
источник