gpt4 book ai didi

python - Django:删除ForeignKey相关实例后如何保存模型实例?

转载 作者:行者123 更新时间:2023-12-01 01:35:34 25 4
gpt4 key购买 nike

我使用的是 Django 2.1.1。

我有一个模型Analysis,其中包含一个 MyFile 模型(我为处理文件而编写的模型)的外键:

from polymorphic.models import PolymorphicModel
from django.db.models import Model, DateTimeField, FileField, SET_NULL
from django.db.models.signals import pre_delete

class MyFile(Model):
file = FileField(upload_to='./', null=False, blank=False)
description = CharField(max_length=255, null=True, blank=True)
date_added = DateTimeField(auto_now_add=True)


@receiver(pre_delete, sender=MyFile)
def mymodel_delete(sender, instance, **kwargs):
"""
To delete the file connected to the `sender` class: receive the pre_delete signal
and delete the file associated with the model instance.
"""
instance.file.delete(False)

class Analysis(PolymorphicModel):
# ... other fields ...
file_results = ForeignKey(MyFile, on_delete=SET_NULL,
related_name='file_results',
null=True, blank=True)

Analysis 是一个 PolymorphicModel ,因为与更大的项目相关。

Analysis.file_results 中,我设置了 on_delete=SET_NULL 因为我希望即使没有 file_result 也允许 Analysis 实例存在,稍后可以填充。

假设我添加了一些文件(MyFile 表有几行)和一些 Analysis 实例。现在,如果我想删除与 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_delete 信号上调用的 mymodel_delete 函数可以正常工作。但是,我真的不明白如何解决ValueError

有趣的是,我注意到以下几行工作正常,即不引发任何 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_results Python 对象仍然存在,并且引用了现在丢失的数据库行。 documentation for delete()提到这一点:

This only deletes the object in the database; the Python instance will still exist and will still have data in its fields.

因此,如果您想继续使用实例对象,只需自行将属性设置为 None 即可。与上面的代码类似,只是您不需要临时对象。

a = Analysis.objects.get(pk=0)
a.file_results.delete()
a.file_results = None

# ... more operations on a

a.save() # no error

关于python - Django:删除ForeignKey相关实例后如何保存模型实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52429774/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com