2017-03-16 19 views
7

मैं django प्रबंधक (model.Manager) पर get_by_natural_key विधि को फिर से लिखने की कोशिश कर रहा हूं। मॉडल (NexchangeModel) जोड़ने के बाद मैं सभी() ऑब्जेक्ट्स को हटा सकता हूं लेकिन एकल - नहीं कर सकता।Django मॉडल को फिर से लिखने के बाद एकल ऑब्जेक्ट को हटा नहीं सकता है। प्रबंधक विधि

कर सकते हैं:

SmsToken.objects.all().delete() 

नहीं कर सकते:

SmsTokent.objects.last().delete() 

कोड:

from django.db import models 
from core.common.models import SoftDeletableModel, TimeStampedModel, UniqueFieldMixin 

class NexchangeManager(models.Manager): 
    def get_by_natural_key(self, param): 
     qs = self.get_queryset() 
     lookup = {qs.model.NATURAL_KEY: param} 
     return self.get(**lookup) 


class NexchangeModel(models.Model): 
    class Meta: 
     abstract = True 
    objects = NexchangeManager() 

class SmsToken(NexchangeModel, SoftDeletableModel, UniqueFieldMixin): 
    sms_token = models.CharField(
     max_length=4, blank=True) 
    user = models.ForeignKey(User, related_name='sms_token') 
    send_count = models.IntegerField(default=0) 
+0

प्रयास करने पर क्या होता है? –

+0

सभी पर() मुझे संदेश हटा रहा है .: i.e: (1, {'accounts.SmsToken': 1})। आखिरी() कुछ भी नहीं (कोई नहीं) लेकिन इसे एक समान संदेश भी देना चाहिए (रिकॉर्ड का पीके जो अभी हटा दिया गया था)। –

+1

'सभी()' एक 'क्वेरीसेट', 'अंतिम()' एक उदाहरण देता है। इसलिए मैं अलग-अलग व्यवहार से आश्चर्यचकित नहीं होगा, क्योंकि पहला डिलीट-फ़ंक्शन प्रबंधक/क्वेरीसेट में से एक है और दूसरा आपके मॉडल में से एक है। बेशक यह समझा नहीं जाता है कि क्यों हटाना काम नहीं करता है ... – arie

उत्तर

8

आपको बुला रहे हैं: SmsToken.objects.all().delete() आप क्वेरीसमूह के हटाने विधि बुला रहे हैं।

लेकिन SmsTokent.objects.last().delete() पर आप इंस्टेंस की डिलीट विधि को कॉल कर रहे हैं।

django के बाद 1.9 क्वेरीसेट delete विधि आइटमों को हटाया नहीं जाता है। REF

Django 1.9 में परिवर्तित: वापसी मान जोड़ा गया है नष्ट कर दिया वस्तुओं की संख्या का वर्णन।

लेकिन उदाहरण पर delete विधि Django पहले से ही जानता है कि केवल एक पंक्ति हटा दी जाएगी।

यह भी ध्यान दें कि क्वार्सेट की डिलीट विधि और इंस्टेंस की डिलीट विधि अलग-अलग हैं।

हटाएँ() [on a querset] विधि एक थोक हटाना करता है और अपने मॉडल [instance method] पर किसी भी हटाने() पद्धतियों फोन नहीं करता है। हालांकि, यह सभी हटाए गए ऑब्जेक्ट्स (कैस्केड डिलीशन सहित) के लिए pre_delete और post_delete संकेतों को छोड़ देता है।

तो आप यह जांचने के लिए विधि की प्रतिक्रिया पर भरोसा नहीं कर सकते कि डिलीट ठीक काम करता है या नहीं। लेकिन पाइथन के दर्शन के संदर्भ में "अनुमति के मुकाबले क्षमा मांगें"। इसका मतलब यह है कि आप यह देखने के लिए अपवादों पर भरोसा कर सकते हैं कि क्या एक डिलीट ठीक तरीके से काम कर रहा है या नहीं। Django के ओआरएम उचित अपवाद उठाएगा और किसी भी विफलता के मामले में उचित रोलबैक करेगा।

तो तुम यह कर सकते हैं:

try: 
    instance.delete()/querset.delete() 
except Exception as e: 
    # some code to notify failure/raise to propagate it 
    # you can avoid this try..except if you want to propagate exceptions as well. 

नोट: मैं सामान्य अपवाद को पकड़ने हूँ क्योंकि मेरी कोशिश ब्लॉक में केवल कोड delete है। यदि आप कुछ अन्य कोड चाहते हैं तो आपको केवल विशिष्ट अपवादों को पकड़ना होगा।

5

मुझे लगता है कि SoftDeletableModeldjango-model-utils पैकेज से आता है? यदि ऐसा है, तो उस मॉडल के purpose को वास्तव में उन्हें हटाने के बजाय is_removed फ़ील्ड के साथ उदाहरणों को चिह्नित करना है। तो यह उम्मीद की जा रही है कि मॉडल उदाहरण पर delete() पर कॉल करना-जो आपको last() से मिलता है-वास्तव में कुछ भी हटा नहीं सकता है।

SoftDeletableModelprovides एक manager कि गैर हटा वस्तुओं के लिए अपने परिणामों को सीमित करता है, और delete() ओवरराइड करता है के रूप में के बजाय वास्तव में उन्हें हटाने की वस्तुओं को निकालकर चिह्नित करने के लिए के साथ एक objects विशेषता।

समस्या यह है कि आपने अपने प्रबंधक को objects के रूप में परिभाषित किया है, इसलिए SoftDeletableModel प्रबंधक का उपयोग नहीं किया जा रहा है। आपका कस्टम मैनेजर वास्तव में डेटाबेस से ऑब्जेक्ट्स को हटा रहा है, नरम डिलीट करने के लक्ष्य के विपरीत। इसका समाधान करने का तरीका यह है कि आपका कस्टम मैनेजर SoftDeletableManagerMixin:

class NexchangeManager(SoftDeletableManagerMixin, models.Manager): 
    # your custom code 
संबंधित मुद्दे