0
06
41
17
为了账号安全,请及时绑定邮箱和手机立即绑定

Django:如何在删除与外键相关的实例后保存模型实例?

Django:如何在删除与外键相关的实例后保存模型实例?

DIEA 2021-06-11 22:18:46
我正在使用 Django 2.1.1。我有一个模型Analysis,其中包含一个MyFile模型的外键(我编写的用于处理文件的模型):from polymorphic.models import PolymorphicModelfrom django.db.models import Model, DateTimeField, FileField, SET_NULLfrom django.db.models.signals import pre_deleteclass 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因为我希望Analysis即使没有 也允许实例存在file_result,稍后可以填充。假设我添加了一些文件(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.nameValueError: save() prohibited to prevent data loss due to unsaved            related object 'file_results'.当文件实际上从文件系统中删除时,mymodel_delete在pre_delete信号上调用的函数可以正常工作。但是,我真的不明白如何解决ValueError.但是,这是这样做的正确方法吗?删除相关对象的最佳做法是什么?
查看完整描述

1 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

首先,请注意,您不需要save()仅仅因为delete(). 将delete()根据需要将更新数据库。


也就是说,想要继续使用该实例来执行其他操作是合理的,从而导致save(). 您收到错误的原因是a.file_resultsPython 对象仍然存在,并且引用了现在丢失的数据库行。在对文件delete()提到了这一点:


这只会删除数据库中的对象;Python 实例仍将存在,并且其字段中仍将有数据。


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


a = Analysis.objects.get(pk=0)

a.file_results.delete()

a.file_results = None


# ... more operations on a


a.save()  # no error


查看完整回答
反对 回复 2021-06-22

添加回答

代码语言

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号