Python Django:删除ForeignKey相关实例后如何保存模型实例?
我正在使用Django 2.1.1 我有一个模型Python Django:删除ForeignKey相关实例后如何保存模型实例?,python,django,django-models,Python,Django,Django Models,我正在使用Django 2.1.1 我有一个模型Analysis,其中包括MyFile模型的外键(我编写该模型是为了处理文件): Analysis是一个PolymorphicModel,其原因与更大的项目有关 在Analysis.file\u results中,我将设置为\u delete=set\u NULL,因为我想允许分析实例存在,即使没有文件\u result,以后也可以填充 假设我添加了几个文件(MyFile表中有几行)和几个分析实例。现在,如果我想删除与Analysis实例之一相关的
Analysis
,其中包括MyFile
模型的外键(我编写该模型是为了处理文件):
Analysis
是一个PolymorphicModel
,其原因与更大的项目有关
在Analysis.file\u results
中,我将设置为\u delete=set\u NULL
,因为我想允许分析
实例存在,即使没有文件\u result
,以后也可以填充
假设我添加了几个文件(MyFile表中有几行)和几个分析实例。现在,如果我想删除与Analysis
实例之一相关的文件,我会:
a = Analysis.objects.get(pk=0)
a.file_results.delete()
a.save()
但我得到了以下错误:
File "/Users/mtazzari/djangos/views.py" in update_job_refs
377. a.save()
File "/Users/mtazzari/anaconda/envs/djangos/lib/python3.6/site-packages/polymorphic/models.py" in save
83. return super(PolymorphicModel, self).save(*args, **kwargs)
File "/Users/mtazzari/anaconda/envs/djangos/lib/python3.6/site-packages/django/db/models/base.py" in save
670. "unsaved related object '%s'." % field.name
ValueError: save() prohibited to prevent data loss due to unsaved
related object 'file_results'.
当文件从文件系统中实际删除时,在pre\u delete
信号上调用的mymodel\u delete
函数正常工作。
然而,我真的不明白如何解决值错误
有趣的是,我注意到以下几行工作正常,即不引发任何ValueError,将文件从文件系统中删除,并将a.file_results
中的FK设置为Null:
a = Analysis.objects.get(pk=0)
tmp = a.file_results
a.file_results = None
tmp.file_results.delete()
a.save()
但是,这是一种正确的方法吗?删除相关对象的最佳实践是什么
谢谢 首先,请注意,您不需要仅仅因为delete()
而save()
。delete()
将根据需要更新数据库
也就是说,继续使用实例执行其他操作是合理的,这会导致save()
。出现错误的原因是a.file\u results
Python对象仍然存在,并且引用了一个现在丢失的数据库行。报告提到:
这只会删除数据库中的对象;Python实例仍然存在,并且其字段中仍然有数据
因此,如果要继续使用实例对象,只需自己将属性设置为None
。与上面的代码类似,只是不需要temp对象
a = Analysis.objects.get(pk=0)
a.file_results.delete()
a.file_results = None
# ... more operations on a
a.save() # no error
谢谢你的澄清!我以前在文档中读过这句话,但我发现它非常模糊,因为它没有说明如何处理Python实例,不管是否可以忘记它。你的解决方案有效。鉴于Python实例不再严格有效,我希望默认情况下可以在.delete()
方法中添加a.file\u results=None
。@mtazzari:MyFile.delete()
方法不知道有关a
的任何内容,也不知道可能指向它的任何其他名称。考虑执行a.delete()
:是否应该将a
名称从范围中消失?Python就是不是这样工作的。
a = Analysis.objects.get(pk=0)
a.file_results.delete()
a.file_results = None
# ... more operations on a
a.save() # no error