Natknąłem się na to pytanie i mam dla ciebie rozwiązanie. Zauważ, że django==1.6
nie jest obsługiwany dłużej, więc rozwiązanie to prawdopodobnie będzie działać na django>=1.9
Powiedzmy mówimy o 2 obiektów na teraz:
class FileReference(models.Model):
pass
class Person(models.Model):
avatar = models.ForeignKey(FileReference, related_name='people_with_avatar', on_delete=models.CASCADE)
Jak widać w ForeignKey.on_delete dokumentacji, po usunięciu powiązanego obiektu FileReference
usuwany jest również obiekt odwoływania Person
.
Teraz za twoje pytanie. Jak robimy czczony? Chcemy, aby po Person
usunięto również obiekt FileReference
.
Zrobimy to za pomocą 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)
Co zrobiliśmy było usunięcie odniesienia w dziedzinie avatar
na Person
usunięciem. Zauważ, że blok try: except:
ma zapobiegać wyjątkom w pętli.
Extra:
Powyższe rozwiązanie będzie działać na wszystkich przyszłych obiektów. Jeśli chcesz usunąć wszystkie z ostatnich obiektów bez odniesienia należy wykonać następujące czynności:
W pakiecie dodać następujące pliki i katalogi: 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()
Kiedy zrobić, zadzwoń: python manage.py remove_unused_file_reference
To pomysł bazowy, możesz go zmienić na zbiorczy usuń itd ...
Mam nadzieję, że to pomoże komuś tam. Powodzenia!
Użyj 'Collector': http://stackoverflow.com/a/12162619/548165 – catavaran
@catavaran Próbowałem, kiedy wywołuję' collector.collect (file_ref_obj) ', to podnosi:' TypeError: 'FileReference' obiekt nie obsługuje indeksowania' –
Przekaż listę pojedynczą instancją: 'collector.collect ([file_ref_obj])' – catavaran