Mi sono imbattuto in questa domanda e ho trovato una soluzione per voi. Si noti, che django==1.6
non è supportato più, quindi questa soluzione probabilmente funzionerà sulla django>=1.9
Diciamo che stiamo parlando di due degli oggetti, per ora:
class FileReference(models.Model):
pass
class Person(models.Model):
avatar = models.ForeignKey(FileReference, related_name='people_with_avatar', on_delete=models.CASCADE)
Come si può vedere nel ForeignKey.on_delete documentazione, quando si elimina l'oggetto FileReference
correlato, viene eliminato anche l'oggetto di riferimento Person
.
Ora per la tua domanda. Come facciamo i riveriti? Vogliamo la cancellazione Person
che l'oggetto FileReference
verrà rimosso anche.
Lo faremo utilizzando 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)
Quello che abbiamo fatto c'era la soppressione del riferimento nel avatar
campo su Person
eliminazione. Si noti che il blocco try: except:
impedisce le eccezioni di loop.
Extra:
La soluzione di cui sopra funziona su tutti gli oggetti futuri. Se si desidera rimuovere tutti gli oggetti passati senza un riferimento effettuare le seguenti operazioni:
Nel pacchetto aggiungere il seguente file e directory: 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()
volta finito, chiamare: python manage.py remove_unused_file_reference
Questo è il idea base, puoi cambiarla in bulk delete, ecc ...
Spero che questo possa aiutare qualcuno là fuori. In bocca al lupo!
Utilizzare il 'Collector': http://stackoverflow.com/a/12162619/548165 – catavaran
@catavaran Ho provato che, quando chiamo' collector.collect (file_ref_obj) ', solleva:' TypeError: 'FileReference' l'oggetto non supporta l'indicizzazione' –
Passa una lista con la singola istanza: 'collector.collect ([file_ref_obj])' – catavaran