Синхронизированные экземпляры модели в Django - PullRequest
0 голосов
/ 03 апреля 2020

Я строю модель для проекта Django (мой первый проект Django) и заметил, что экземпляры модели Django не синхронизированы.

a_note = Notes.objects.create(message="Hello")  # pk=1
same_note = Notes.objects.get(pk=1)

same_note.message = "Good day"
same_note.save()

a_note.message  # Still is "Hello"

a_note is same_note  # False

Есть ли встроенный -в способ сделать экземпляры модели с тем же первичным ключом, чтобы тот же объект? Если да, (как) это поддерживает глобально непротиворечивое состояние всех объектов модели, даже в случае массовых обновлений или изменения внешних ключей и, таким образом, заставляет элементы входить / выходить из связанных наборов?

Я могу представить какой-то вид реестра в модельном классе, который мог бы, по крайней мере, обрабатывать простые случаи (т. е. отказывать в случае массовых обновлений или изменения внешних ключей). Однако реестр stati c усложняет тестирование.

Я намереваюсь построить (доменную) модель с высокоуровневыми функциями для выполнения сложных операций, которые go выходят за рамки простых действий CRUD Django Класс Model. (Некоторые классы моей модели имеют экземпляр подкласса Django Model, в отличие от , являющегося экземпляром подкласса. Это сделано для предотвращения прямого доступа к база данных, которая может нарушить согласованность и отделить бизнес-логику c от чисто доступа к данным Django Model.) Сложная операция может коснуться и изменить несколько компонентов. Как разработчик, использующий API модели, невозможно узнать, какие компоненты устарели после вызова сложной операции. Автоматически синхронизированные экземпляры могут смягчить эту проблему. Есть ли другие способы преодолеть это?

1 Ответ

1 голос
/ 03 апреля 2020

TL; DR "Есть ли встроенный способ сделать экземпляры модели с одним и тем же первичным ключом одним и тем же объектом?" Нет .

Объект python в памяти - это не то же самое, что строка в вашей базе данных. Поэтому, когда вы создаете a_note и затем извлекаете same_note из базы данных, это два разных объекта в памяти , даже если они представляют собой одно и то же представление базовой строки в вашей базе данных. Когда вы выбираете same_note, фактически вы создаете новый объект Notes и инициализируете его значениями, извлеченными из базы данных.

Затем вы изменяете и сохраняете same_note, но объект a_note в памяти не изменился. Если бы вы сделали a_note.refresh_from_db(), вы бы увидели, что a_note.message был изменен.

Теперь a_note is same_note всегда будет False, потому что расположение в памяти этих двух объектов всегда будет различным. Две переменные одинаковы (is равно True), если они указывают на один и тот же объект в памяти.

Но a_note == same_note вернет True в любое время, поскольку Django определяет два экземпляра модели равными , если их pk одинаковы .

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

В рамках одного запроса, поскольку все является последовательным и однопоточным, нет риска, что переменные выйдут из-под контроля c: Вы знаете порядок, в котором все делается, и поэтому всегда можете вызвать refresh_from_db(), когда вы знаю, что предыдущий вызов метода мог изменить значение базы данных.

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

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