python - 如何在不使用 refresh_from_db 的情况下强制 Django 模型在保存后重新加载字段?
问题描述
我有以下 Django 模型: 设备有一个部署的外键 我在设备中有一个采用方法,它为设备设置部署并执行一些额外的逻辑。
请注意,我将 id 而不是 Deployment 实例传递给了采用方法
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)
如果我无法访问设备实例的部署字段,则采用()按预期工作。例子:
device = Device.objects.get(pk=device_id)
device.adopt(deployment_id) # this works
相反,如果我在调用采用之前加载部署字段,当我调用采用时,我会得到一个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(请参阅采用方法中的注释),但这会生成一个我想避免的额外查询。有没有办法强制模型忘记不涉及额外查询的部署属性的“缓存”值?
编辑:澄清引发异常的位置
解决方案
我不确定我是否理解正确,但对我来说,问题似乎在于部署的默认值为空。因此,如果您尝试访问部署而不首先分配部署对象,它将为空。
请在调用 device.deployment 之前检查您是否正在分配部署,如果是,请提供一些代码,以便我重新创建您的情况。
推荐阅读
- javascript - $(this).attr('id)) 返回未定义的值
- python - 如何在 TensorFlow 矩中设置轴参数以进行批量标准化?
- javascript - 在 CSS 中制作一个带有圆形边框和渐变的碗/微笑/半圆
- python - 添加 __getattribute__ 以打印字符串类型的消息
- c# - SerialPort.Open 抛出“传递给系统调用的数据区域太小”异常
- python - Python 相对导入导致 pylint 错误
- python - 如何处理用户创建的小部件?
- javascript - 动态更新 JavaScript 数组
- javascript - Javascript - 如何从响应中检索 html 标记的值
- c++ - 检查输入是否为数字或字符