У меня есть следующие модели 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), но это создаст дополнительный запрос, который мне бы хотелосьизбежать.Есть ли способ заставить модель забыть «кэшированное» значение атрибута развертывания, которое не включает дополнительный запрос?
редактировать: уточнено, где возникает исключение