Django: 通过外键查找所有反向引用

2024-10-01 11:33:46 发布

您现在位置:Python中文网/ 问答频道 /正文

现在我用的是django1.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对象。在

但是其他地方会有外键。在

有没有什么有效的方法可以找到所有的参考资料?i、 获取某个模型对象的引用计数?在


Tags: 对象name模型dataattachmentmodelmodelswith
1条回答
网友
1楼 · 发布于 2024-10-01 11:33:46

我偶然发现了这个问题,我给你找到了一个解决办法。请注意,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

^{pr2}$

我们所做的是删除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 这是基本思想,你可以把它改成批量删除等等。。。在

我希望这会对其他人有所帮助。祝你好运!在

相关问题 更多 >