2010-07-19 11 views
9

मैं देरी ब्लॉग पोस्ट हटाने योजना को लागू करने की कोशिश कर रहा हूं। तो एक परेशान के बजाय क्या आप निश्चित हैं?, आपको हटाने को रद्द करने के लिए 2 मिनट का समय सीमा मिलती है।ऐप इंजन पायथन मॉडल क्लास के कस्टम __init__ का सही तरीके से उपयोग कैसे करें?

मैं ट्रैक करने के लिए, क्या हटा दिया जाएगा जब एक db.Model वर्ग (DeleteQueueItem) के साथ के रूप में मैं कतार से किसी कार्य को हटाने के लिए कोई रास्ता मिल चाहते हैं और मैं क्या वहाँ क्वेरी कर सकता है संदेह है।

एक DeleteQueueItem इकाई बनाना स्वचालित रूप से एक delete_when गुण सेट और कतार में एक कार्य जोड़ने चाहिए। मैं ब्लॉग पोस्ट के सापेक्ष पथ का उपयोग उनके key_name के रूप में करता हूं और इसे key_name के रूप में भी उपयोग करना चाहता हूं। यह मैं एक कस्टम init को जन्म दिया:

class DeleteQueueItem(db.Model): 
    """Model to keep track of items that will be deleted via task queue.""" 

    # URL path to the blog post is handled as key_name 
    delete_when = db.DateTimeProperty() 

    def __init__(self, **kwargs): 
     delay = 120 # Seconds 
     t = datetime.timedelta(seconds=delay) 
     deadline = datetime.datetime.now() - t 
     key_name = kwargs.get('key_name') 

     db.Model.__init__(self, **kwargs) 
     self.delete_when = deadline 

     taskqueue.add(url='/admin/task/delete_page', 
         countdown=delay, 
         params={'path': key_name}) 

यह काम करने के लिए, जब तक मैं इकाई को हटाने का प्रयास लगता है:

TypeError: __init__() takes exactly 1 non-keyword argument (2 given) 

क्या बजे:

fetched_item = models.DeleteQueueItem.get_by_key_name(path) 

इस के साथ विफल मैं गलत कर रहा हूँ?

उत्तर

15

आम तौर पर, आपको मॉडल कक्षाओं की init विधि को आजमाने और ओवरराइड नहीं करना चाहिए। हालांकि सही होने के लिए संभव है, सही कन्स्ट्रक्टर व्यवहार काफी जटिल है, और रिलीज के बीच भी बदल सकता है, अपना कोड तोड़ सकता है (हालांकि हम ऐसा करने से बचने की कोशिश करते हैं!)। इसका कारण यह है कि निर्माता को डेटास्टोर से लोड किए गए मॉडलों का पुनर्निर्माण करने के लिए, नए मॉडल बनाने और ढांचे के माध्यम से, अपने स्वयं के कोड द्वारा दोनों का उपयोग किया जाना चाहिए।

एक बेहतर तरीका कारखाने विधि का उपयोग करना है, जिसे आप निर्माता के बजाए कॉल करते हैं।

इसके अलावा, आप संभवतः कार्य समय के बजाय इकाई लिखते समय कार्य को जोड़ना चाहते हैं। यदि आप नहीं करते हैं, तो आप दौड़ की स्थिति के साथ समाप्त होते हैं: नई इकाई को डेटास्टोर में संग्रहीत करने से पहले कार्य निष्पादित हो सकता है!

class DeleteQueueItem(db.Model): 
    """Model to keep track of items that will be deleted via task queue.""" 

    # URL path to the blog post is handled as key_name 
    delete_when = db.DateTimeProperty() 

    @classmethod 
    def new(cls, key_name): 
     delay = 120 # Seconds 
     t = datetime.timedelta(seconds=delay) 
     deadline = datetime.datetime.now() - t 

     return cls(key_name=key_name, delete_when=deadline) 

    def put(self, **kwargs): 
     def _tx(): 
     taskqueue.add(url='/admin/task/delete_page', 
         countdown=delay, 
         params={'path': key_name}, 
         transactional=True) 
     return super(DeleteQueueItem, self).put(**kwargs) 
     if not self.is_saved(): 
     return db.run_in_transaction(_tx) 
     else: 
     return super(DeleteQueueItem, self).put(**kwargs) 
+0

महान है, धन्यवाद:

यहाँ एक सुझाव दिया रिफैक्टरिंग है! उसमें एक समस्या है, जहां मुझे एक सुरुचिपूर्ण समाधान के बारे में सोचने में कठिनाई होती है, यह है कि देरी और key_name def _tx() में उपलब्ध नहीं है। – thorwil

+0

ओह, अच्छा बिंदु। आप वर्ग के सदस्य (उदाहरण के लिए, शीर्ष स्तर पर) के रूप में 'देरी' को परिभाषित कर सकते हैं, क्योंकि यह स्थिर होता प्रतीत होता है, और कुंजी नाम को self.key()। Name() के रूप में एक्सेस किया जा सकता है। –

+0

इसे काम करने के लिए मिला! कक्षा के सदस्य के रूप में देरी पर्याप्त स्पष्ट थी, लेकिन मैं self.key() नाम() पर कभी नहीं पहुंचेगा। एक बार फिर धन्यवाद! – thorwil

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