В чем разница между ключом django foreigin в строке и без строки? - PullRequest
3 голосов
/ 07 июля 2019

Я не понимаю, почему люди пишут внешний ключ двумя способами, и какова цель этого? они оба одинаковые или разные?

Я заметил, что некоторые люди пишут как:

author = models.ForeignKey(Author, on_delete=models.CASCADE)

и некоторые люди пишут это так:

author = models.ForeignKey('Author', on_delete=models.CASCADE)

Чем они отличаются? Есть ли какая-то особая цель написания таких слов или они одинаковые?

Ответы [ 2 ]

1 голос
/ 07 июля 2019

Чем они отличаются?Есть ли какая-то особая цель написания, подобного этому, или они оба одинаковые?

Они оба приводят к одной и той же ссылке да.Позже строка будет «разрешена», и в конечном итоге ForeignKey будет указывать на модель Author.

Однако использование строк иногда является единственным способом сделать ссылки, если модели, на которые вы нацеливаетесьдолжны быть определены еще.Например, в случае циклической ссылки.

Представьте, например, что вы определяете отношения как:

class Author(models.Model):
    name = models.CharField(max_length=128)
    favorite_book = models.ForeignKey(<s>Book</s>, null=True, on_delete=models.SET_NULL)

class Book(models.Model):
    title = models.CharField(max_length=128)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

Здесь Book относится к Author и Author относится к Book.Но поскольку класс Book не создается во время создания ForeignKey, это даст NameError.

. Мы не можем определить Author после того, как мы определили Book,с тех пор мы обращаемся к Author до его создания (и, таким образом, это снова даст NameError).

Однако мы можем использовать здесь строки, избегая циклической ссылки, например:

class Author(models.Model):
    name = models.CharField(max_length=128)
    favorite_book = models.ForeignKey(<b>'Book'</b>, null=True, on_delete=models.SET_NULL)

class Book(models.Model):
    title = models.CharField(max_length=128)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

При использовании строки это нормально для интерпретатора Python, так как вы не используете идентификатор, который еще не определен, и Django затем, когда модели будут загружены, заменит строки со ссылкой насоответствующая модель.

Документация на ForeignKey [Django-doc] :

Если вам нужно создать отношение к модели, которая еще не была определена , вы можете использовать имя модели, а не сам объект модели (...)

Если модельопределенный в другом приложении, вы можете обратиться к нему с помощью app_name.ModelName.

1 голос
/ 07 июля 2019

Допустим, вы выложили свои модели следующим образом:

models/
    __init__.py
    model_a.py
    model_b.py

Это обычная схема, когда у вас есть приложение с большим количеством моделей, и вы хотите лучше организовать свой код.Теперь скажите, ModelA имеет внешний ключ для ModelB, а ModelB имеет внешний ключ для ModelA.Вы не можете иметь оба файла, импортирующие другую модель, потому что у вас был бы циклический импорт.

Ссылка на другую модель по строке позволяет вам «лениво» ссылаться на другую модель, которая еще не загружена, это решает проблему наличиякруговой импорт

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...