我正在使用 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
添加回答
舉報
0/150
提交
取消