2015-03-20 9 views
8

खैर, अब मैं Django 1.6+Django: विदेशी कुंजी

उपयोग कर रहा हूँ द्वारा सभी रिवर्स संदर्भ लगता है और मैं एक मॉडल है:

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 ऑब्जेक्ट्स को कोई विदेशी कुंजी संदर्भ के साथ हटाना चाहता हूं।

लेकिन कई अन्य स्थानों में विदेशी कुंजी होगी।

क्या सभी संदर्भों को खोजने के लिए कोई कुशल तरीका है? यानी कुछ मॉडल ऑब्जेक्ट की संदर्भ संख्या प्राप्त करें?

+2

'कलेक्टर' का प्रयोग करें: http://stackoverflow.com/a/12162619/548165 – catavaran

+0

@catavaran मैंने कोशिश की, जब मैं 'collector.collect (file_ref_obj) 'कहता हूं, तो यह उठाता है:' TypeError: 'FileReference' ऑब्जेक्टिंग का समर्थन नहीं करता है –

+0

एकल उदाहरण के साथ एक सूची पास करें: 'collector.collect ([file_ref_obj])' – catavaran

उत्तर

0

मैंने इस प्रश्न पर ठोकर खाई और मुझे आपके लिए समाधान मिला। ध्यान दें, कि django==1.6 किसी भी अधिक समर्थित नहीं है, तो यह समाधान शायद django>=1.9

पर काम करेंगे कहते हैं कि हम अब के लिए वस्तुओं के बारे में 2 बात कर रहे हैं देता है:

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) 

हम क्या वहाँ Person विलोपन पर avatar क्षेत्र में संदर्भ को हटाने गया था। ध्यान दें कि 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 यह वह जगह है आधार विचार, आप इसे थोक हटाने आदि में बदल सकते हैं ...

मुझे आशा है कि इससे वहां किसी को भी मदद मिलेगी। शुभ लाभ!

संबंधित मुद्दे