Как заставить модель Django перезагрузить поля после сохранения без использования refresh_from_db? - PullRequest
0 голосов
/ 06 июня 2019

У меня есть следующие модели Django: Устройство имело внешний ключ для развертывания У меня есть метод принятия в Device, который устанавливает развертывание для устройства и выполняет некоторую дополнительную логику.

обратите внимание, что я передаю идентификатор ине экземпляр развертывания для метода принятия

class Device(Model):
    id = models.UUIDField(primary_key=True)
    deployment = models.ForeignKey(
        Deployment, on_delete=models.SET_NULL, blank=True, null=True, related_name='devices'
    )

    def adopt(self, deployment_id):
        self.deployment_id = deployment_id
        self.full_clean()

        with transaction.atomic():
            self.save()

            # self.refresh_from_db()

            if self.deployment.private: # this might fail.. see examples
                # additional logic
                pass


class Deployment(TimeStampedModel, DeploymentResource):
    id = models.UUIDField(primary_key=True)
    name = models.CharField(max_length=150)
    private = models.BooleanField(default=False)

Если у меня нет доступа к полю развертывания экземпляра устройства, метод accept () работает как положено.пример:

device = Device.objects.get(pk=device_id)
device.adopt(deployment_id) # this works

, если вместо этого я загружаю поле развертывания перед вызовом accept, при вызове Adopt я получаю AttributeError: 'NoneType' object has no attribute 'private'

, это не работает:

device = Device.objects.get(pk=device_id)
print(device.deployment) # example of accessing/loading the field/relation
device.adopt(deployment_id) # this will generate the attribute error

Причина довольно очевидна.device.deployment имеет значение None, его значение было загружено и сохранено внутри модели, но оно не загружается автоматически и не заменяется новым развертыванием после вызова save ().Первый пример работает просто потому, что перед сохранением никогда не обращались к отношению к развертыванию.

Очевидное решение - вызвать refresh_from_db после сохранения (см. Комментарий в методе accept), но это создаст дополнительный запрос, который мне бы хотелосьизбежать.Есть ли способ заставить модель забыть «кэшированное» значение атрибута развертывания, которое не включает дополнительный запрос?

редактировать: уточнено, где возникает исключение

1 Ответ

0 голосов
/ 06 июня 2019

Я не уверен, правильно ли я понимаю, но мне кажется, что проблема скорее в том, что значение развертывания по умолчанию равно нулю.Поэтому, если вы попытаетесь получить доступ к развертыванию без предварительного назначения объекта развертывания, он будет нулевым.

Пожалуйста, проверьте, назначаете ли вы развертывание, прежде чем вызывать device.deployment, и если да, предоставьте некоторый код, чтобы я мог воссоздать вашу ситуацию.

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