2013-03-04 4 views
11

हटाना मैं admin.py है इस प्रकार है:Django व्यवस्थापक: ओवरराइड विधि

class profilesAdmin(admin.ModelAdmin): 
    list_display = ["type","username","domain_name"] 

अब मैं कुछ काम करवाना चाहते हैं वस्तु को हटाने से पहले यह मुझे एक त्रुटि मिलती है कि self पहला पैरामीटर होना चाहिए।

मैं उपरोक्त फ़ंक्शन को कैसे संशोधित कर सकता हूं?
और मैं हटाए जा रहे ऑब्जेक्ट का प्रोफ़ाइल_नाम पुनर्प्राप्त करना चाहता हूं। यह कैसे किया जा सकता है?

मैं भी कोशिश की अधिभावी delete_model विधि:

def delete_model(self, request, object): 
    filename=object.profile_name+".xml" 
    os.remove(os.path.join(object.type,filename)) 
    object.delete() 

लेकिन यह dosn't काम करता है, तो एक से अधिक ऑब्जेक्ट एक शॉट पर नष्ट कर दिया जाना है।

+0

फिर भी मैं त्रुटि स्वयं परिभाषित नहीं – arjun

उत्तर

5

आप अपने delete_model विधि के साथ सही रास्ते पर हैं। जब django व्यवस्थापक कई वस्तुओं पर एक क्रिया करता है तो यह update function का उपयोग करता है। हालांकि, जैसा कि आप दस्तावेज़ों में देखते हैं, ये क्रियाएं केवल SQL का उपयोग कर डेटाबेस स्तर पर की जाती हैं।

आपको dzango व्यवस्थापक में custom action के रूप में अपनी delete_model विधि जोड़ने की आवश्यकता है।

def delete_model(modeladmin, request, queryset): 
    for obj in queryset: 
     filename=obj.profile_name+".xml" 
     os.remove(os.path.join(obj.type,filename)) 
     obj.delete() 

फिर अपने modeladmin करने के लिए अपने समारोह जोड़ने -

class profilesAdmin(admin.ModelAdmin): 
    list_display = ["type","username","domain_name"] 
    actions = [delete_model] 
+0

क्या make_published है मिलता देख सकते हैं? – arjun

+0

जो लोग, कॉपी और पेस्ट त्रुटि - मैंने अपना जवाब अपडेट कर दिया है। –

+0

यह केवल एक ऑब्जेक्ट को हटाना है, तो यह एक त्रुटि फेंकता है। त्रुटि'_profile 'ऑब्जेक्ट देता है यह इष्टतम नहीं है। इसके अलावा क्रिया सूची में 2 मान होंगे। एक delete_model है और दूसरा चयनित प्रोफाइल हटाएं। – arjun

0

आपका विधि होना चाहिए

class profilesAdmin(admin.ModelAdmin): 
    #... 

    def _profile_delete(self, sender, instance, **kwargs): 
     # do something 

    def delete_model(self, request, object): 
     # do something 

आप हर विधि हस्ताक्षर में पहला तर्क के रूप में वर्तमान वस्तु के लिए एक संदर्भ जोड़ना चाहिए (आमतौर पर self कहा जाता है)। इसके अलावा, delete_model को एक विधि के रूप में कार्यान्वित किया जाना चाहिए।

+0

नहीं, यह संभव नहीं है। अगर मैं स्वयं जोड़ता हूं, तो मुझे त्रुटि मिलती है _profile_delete 3 तर्क लेता है (2 दिया गया) – arjun

4

मुख्य मुद्दा यह है कि Django व्यवस्थापक का थोक हटाना एसक्यूएल का उपयोग करता है, उदाहरण नहीं .delete(), जैसा कि कहीं और उल्लेख किया गया है। एक व्यवस्थापक-केवल समाधान के लिए, निम्नलिखित समाधान Django व्यवस्थापक के "क्या आप वास्तव में इन्हें मिटाना चाहते हैं" को संरक्षित करता है।

सबसे सामान्य समाधान मॉडल के प्रबंधक द्वारा हटाए गए क्वेरीसेट को ओवरराइड करना है ताकि हटाने को रोक दिया जा सके।

from django.contrib.admin.actions import delete_selected 

class BulkDeleteMixin(object): 
    class SafeDeleteQuerysetWrapper(object): 
     def __init__(self, wrapped_queryset): 
      self.wrapped_queryset = wrapped_queryset 

     def _safe_delete(self): 
      for obj in self.wrapped_queryset: 
       obj.delete() 

     def __getattr__(self, attr): 
      if attr == 'delete': 
       return self._safe_delete 
      else: 
       return getattr(self.wrapped_queryset, attr) 

     def __iter__(self): 
      for obj in self.wrapped_queryset: 
       yield obj 

     def __getitem__(self, index): 
      return self.wrapped_queryset[index] 

     def __len__(self): 
      return len(self.wrapped_queryset) 

    def get_actions(self, request): 
     actions = super(BulkDeleteMixin, self).get_actions(request) 
     actions['delete_selected'] = (BulkDeleteMixin.action_safe_bulk_delete, 'delete_selected', ugettext_lazy("Delete selected %(verbose_name_plural)s")) 
     return actions 

    def action_safe_bulk_delete(self, request, queryset): 
     wrapped_queryset = BulkDeleteMixin.SafeDeleteQuerysetWrapper(queryset) 
     return delete_selected(self, request, wrapped_queryset) 

class SomeAdmin(BulkDeleteMixin, admin.ModelAdmin): 
    ... 
1

आप delete_model विधि अधिरोहण करने का प्रयास विफल हो गया क्योंकि जब आप दक्षता कारणों अपने मॉडल के delete() विधि के लिए एक से अधिक ऑब्जेक्ट Django QuerySet.delete() का उपयोग करने, हटाने बुलाया नहीं किया जाएगा।

आप इसे देख सकते हैं https://docs.djangoproject.com/en/1.9/ref/contrib/admin/actions/
शुरुआत चेतावनी

व्यवस्थापक delete_model() घड़ी मॉडल की कॉल delete() https://github.com/django/django/blob/master/django/contrib/admin/options.py#L1005

इसलिए जब आप एक से अधिक ऑब्जेक्ट हटाने के लिए, आप कस्टम हटाने विधि कभी नहीं होगा के रूप में ही है ।

आपके पास दो तरीके हैं।

1. कस्टम हटाएं कार्रवाई।
चयनित आइटमों में से प्रत्येक के लिए Model.delete() को कॉल करना।

2. उपयोग सिग्नल।
आप कक्षा के अंदर नहीं, केवल सिग्नल का उपयोग कर सकते हैं।

आप भी इस सवाल का Django model: delete() not triggered

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