好吧,现在我正在使用Django 1.6 +
我有一个模特:
class FileReference(models.Model):
# some data fields
# ...
pass
class Person(models.Model):
avatar = models.ForeignKey(FileReference, related_name='people_with_avatar')
class House(models.Model):
images = models.ManyToManyField(FileReference, related_name='houses_with_images')
class Document(model.Model):
attachment = models.OneToOneField(FileReference, related_name='document_with_attachment')
因此,许多其他模型将使用引用FileReference
模型的外键。
但有时,删除引用模型,并留下FileReference
个对象。
我想删除没有外键引用的FileReference
对象。
但是其他许多地方都有外键。
有没有找到所有参考资料的有效方法?即获取某个模型对象的引用计数?
答案 0 :(得分:2)
我偶然发现了这个问题,我找到了一个解决方案。请注意,django==1.6
不再受支持,因此此解决方案可能适用于django>=1.9
让我们说现在我们正在谈论其中的两个对象:
class FileReference(models.Model):
pass
class Person(models.Model):
avatar = models.ForeignKey(FileReference, related_name='people_with_avatar', on_delete=models.CASCADE)
正如您在ForeignKey.on_delete文档中所看到的,当您删除相关的FileReference
对象时,也会删除引用的对象Person
。
现在提出你的问题。我们如何做到受人尊敬?我们希望Person
删除FileReference
对象也将被删除。
我们将使用post_delete signal:
执行此操作def delete_reverse(sender, **kwargs):
try:
if kwargs['instance'].avatar:
kwargs['instance'].avatar.delete()
except:
pass
post_delete.connect(delete_reverse, sender=Person)
我们在那里做的是删除avatar
删除Person
字段中的引用。请注意,try: except:
块是为了防止循环异常。
<强>附加强>
上述解决方案适用于所有未来的对象。如果要在没有引用的情况下删除所有过去的对象,请执行以下操作:
在您的包中添加以下文件和目录:management/commands/remove_unused_file_reference.py
from django.core.management.base import BaseCommand, CommandError
class Command(BaseCommand):
def handle(self, *args, **options):
file_references = FileReference.objects.all()
file_reference_mapping = {file_reference.id: file_reference for file_reference in file_references}
persons = Person.objects.all()
person_avatar_mapping = {person.avatar.id: person for person in persons}
for file_reference_id, file_reference in file_reference_mapping.items():
if file_reference_id not in person_avatar_mapping:
file_reference.delete()
完成后,请致电:python manage.py remove_unused_file_reference
这是基本想法,您可以将其更改为批量删除等...
我希望这对那里的人有所帮助。祝你好运!