Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在保存后强制Django模型重新加载字段,而不使用\u db中的刷新\u?_Python_Django_Orm_Model - Fatal编程技术网

Python 如何在保存后强制Django模型重新加载字段,而不使用\u db中的刷新\u?

Python 如何在保存后强制Django模型重新加载字段,而不使用\u db中的刷新\u?,python,django,orm,model,Python,Django,Orm,Model,我有以下Django型号: 设备具有用于部署的外键 我在设备中有一个采用方法,用于设置设备的部署并执行一些附加逻辑 请注意,我向采用方法传递了一个id而不是部署实例 类设备(型号): id=models.UUIDField(主键=True) 部署=models.ForeignKey( 部署,on_delete=models.SET_NULL,blank=True,NULL=True,相关的_name='devices' ) def采用(自部署_id): self.deployment\u id=

我有以下Django型号: 设备具有用于部署的外键 我在设备中有一个采用方法,用于设置设备的部署并执行一些附加逻辑

请注意,我向采用方法传递了一个id而不是部署实例

类设备(型号):
id=models.UUIDField(主键=True)
部署=models.ForeignKey(
部署,on_delete=models.SET_NULL,blank=True,NULL=True,相关的_name='devices'
)
def采用(自部署_id):
self.deployment\u id=部署\u id
self.full_clean()
使用transaction.atomic():
self.save()
#self.refresh_from_db()
如果self.deployment.private:#这可能会失败。。参见示例
#附加逻辑
通过
类部署(TimeStampedModel,DeploymentResource):
id=models.UUIDField(主键=True)
name=models.CharField(最大长度=150)
private=models.BooleanField(默认值=False)
如果我无法访问设备实例的部署字段,则adopt()将按预期工作。 例如:

device=device.objects.get(pk=device\u id)
设备。采用(部署#id)#这有效
相反,如果我在调用采纳之前加载部署字段,那么当我调用采纳时,我会得到一个
AttributeError:“NoneType”对象没有属性“private”

这不起作用:

device=device.objects.get(pk=device\u id)
打印(device.deployment)#访问/加载字段/关系的示例
device.adopt(部署_id)#这将生成属性错误
原因很明显。device.deployment为None,其值已加载并存储在模型中,但不会在save()调用后自动重新加载并替换为新部署。 第一个示例之所以有效,是因为在保存之前从未访问过部署关系

一个显而易见的解决方案是在保存后从_数据库调用refresh_(请参阅采用方法中的注释),但这将生成一个我希望避免的额外查询。 有没有办法强迫模型忘记不涉及额外查询的部署属性的“缓存”值


编辑:澄清了引发异常的位置

我不确定是否正确理解了这一点,但在我看来,问题在于部署的默认值为空。 因此,如果您尝试访问部署而不首先分配部署对象,它将为null


在调用device.deployment之前,请检查您是否正在分配部署,如果是,请提供一些代码,以便我可以重新创建您的情况。

我不确定是否正确理解这一点,但在我看来,问题似乎在于部署的默认值为空。 因此,如果您尝试访问部署而不首先分配部署对象,它将为null


在调用device.deployment之前,请检查您是否正在分配展开,如果是,请提供一些代码,以便我可以重新创建您的情况。

如果您查看“采用方法”的第一行,我正在分配足以创建关系的展开id。但不方便的是,它将部署保留为无。如果以前没有加载部署字段,则这不是问题。一种选择是将部署实例而不是部署id传递给采用方法,但这是我想要避免的事情。我不是这个意思。如果我正确理解了您的代码,则您只能使用adopt()将部署分配给您的设备。但是,您正在尝试访问device.deployment,然后使用adopt()将其分配给它,因此它将为None。在采用后调用print(device.deployment)时是否仍面临此问题?正确我使用采用方法将部署分配给设备。我可能不清楚的是,属性错误是由以下行生成的:
if self.deployment.private:
在采用方法中。因此,没有“采用后”打印(device.deployment)只是“加载”部署值的一个示例。一个更有意义的例子可能是以下内容:`device=device.objects.get(pk=device\u id)if device.deployment为None:device.adoption(deployment\u id)else:logger.warning('device ready adopted')`我的问题是,如果我在调用adoption之前访问部署,那么adopt会失败,因为它的值已加载并保存在内存中。我想找到一种方法使这个“缓存”值无效,这样它在保存新的真实关系后会重新加载。啊,我想我现在明白了。我回家后会重新创建它,因为我很确定我从来没有遇到过这个问题。如果你看一下采用方法的第一行,我会分配部署id,这足以创建关系。但不方便的是,它将部署保留为无。如果以前没有加载部署字段,则这不是问题。一种选择是将部署实例而不是部署id传递给采用方法,但这是我想要避免的事情。我不是这个意思。如果我正确理解了您的代码,则您只能使用adopt()将部署分配给您的设备。但是,您正在尝试访问device.deployment,然后使用adopt()将其分配给它,因此它将为None。在采用后调用print(device.deployment)时是否仍面临此问题?正确我使用采用方法将部署分配给设备。我可能不清楚的是,属性错误是由以下行生成的:
if self.deployment.private:
在采用方法中。因此,没有“采用后”打印(device.deployment)只是“加载”部署值的一个示例。一个更有意义的示例可能是以下内容:`device=device.objects.get(pk=device\u id)如果device.deployment为None:device.adoption(deployment\u id)else:logger.warning('device alread