2015-03-04 3 views
9

यदि मेरे पास Property उदाहरणों के साथ किसी GET या POST अनुरोध से कुछ (स्ट्रिंग) मान हैं, तो एक IntegerProperty और एक TextProperty कहें, क्या मूल्यों को उचित (उपयोगकर्ता) प्रकारों में लंबे समय तक कठोर श्रृंखला के बिना रूपांतरित करने का कोई तरीका है isinstance कॉल?एनडीबी संपत्ति के लिए एक स्ट्रिंग को उचित प्रकार में बदलने के लिए सही तरीका?

मैं कार्यक्षमता की इस तरह (सभी इनपुट सत्यापन स्पष्टता के लिए छोड़े गए) पुन: पेश करने के लिए देख रहा हूँ:

for key, value in self.request.POST.iteritems(): 
    prop = MyModel._properties[key] 

    if isinstance(prop, ndb.IntegerProperty): 
     value = int(value) 
    elif isinstance(prop, (ndb.TextProperty, ndb.StringProperty)): 
     pass # it's already the right type 
    elif ... 
    else 
     raise RuntimeError("I don't know how to deal with this property: {}" 
          .format(prop)) 

    setattr(mymodelinstance, key, value) 

उदाहरण के लिए, यदि कोई IntegerProperty से int वर्ग पाने के लिए एक तरह से और bool वर्ग है BooleanProperty आदि से, यह काम करेगा।

एनडीबी मेटाडाटा एपीआई वास्तव में इस सुंदरता को हल नहीं करता है, जहां तक ​​मैं देख सकता हूं; get_representations_of_kind के साथ मैं मामलों की संख्या को कम कर सकता हूं, हालांकि।

+0

मुझे आपका दर्द महसूस हो सकता है ... एक सवाल हालांकि, आपको ** POST ** आइटम से अपेक्षित डेटा प्रकारों को जानना चाहिए था, इसलिए उम्मीद से ** मूल्य ** प्राप्त क्यों न करें ** कुंजी ** और उन्हें उचित प्रकार में परिवर्तित करें? – Anzel

+0

@Anzel सुनिश्चित नहीं है कि पोस्ट आइटम से अपेक्षित डेटा प्रकार जानने के बारे में आपका क्या मतलब है। मॉडल परिभाषा में मेरे पास कुछ अलग प्रकार के 45 गुण हैं; अपने आप को दोहराने के हित में मैं कहीं भी संपत्ति के नामों और प्रकारों के बीच मैपिंग दोहराना नहीं चाहता हूं लेकिन अभी भी पता है कि "ट्रू" या "5" जैसे मान को बूल, स्ट्रिंग या इंट के रूप में व्याख्या करने की आवश्यकता है या नहीं । –

+0

मैं समझता हूं कि आप क्या करने का प्रयास कर रहे हैं, लेकिन चूंकि आप कनवर्टर पर जा रहे डेटा को जीईटी/पोस्ट डेटा में हैं, इसलिए आप कुंजी/मूल्य जोड़ी को मैप करने के लिए एक रूपांतरण फ़ंक्शन को परिभाषित कर सकते हैं ... – Anzel

उत्तर

0

WTForms नामक एक पायथन पैकेज है जो इसके लिए बहुत उपयोगी है, और आम तौर पर फॉर्म को और अधिक सुखद अनुभव प्रसंस्करण करता है।

class MyForm(wt.Form): 
    text = MyTextAreaField("Enter text") 
    n = wt.IntegerField("A number") 

f = MyForm(self.request.POST) 
f.validate() 
print f.text.data 
print f.n.data 

कॉलिंग f.validate() अपने आप फ़ॉर्म द्वारा निर्दिष्ट डेटा प्रकार में डेटा पोस्ट में परिवर्तित कर देंगे:

यहाँ एक बहुत ही सरल उदाहरण है। तो f.text.data एक स्ट्रिंग होगी और f.n.data एक int होगा।

यह भी अजीब डेटा को गहन रूप से संभालता है। यदि कोई उपयोगकर्ता पूर्णांक फ़ील्ड के लिए एक अक्षर इनपुट करता है, तो f.n.dataNone होगा। आप उन त्रुटि संदेशों को भी निर्दिष्ट कर सकते हैं जिन्हें आसानी से आपके वेब पेज में शामिल किया गया है।

WTForms फॉर्म प्रसंस्करण से बड़ी मात्रा में कठोरता लेता है!

2

आप उपयोगकर्ता के परिभाषित प्रकारों के बीच मानचित्र के लिए type का उपयोग करके कुंजी के रूप में एक अंतर्निहित और अंतर्निहित प्रकार के रूप में उपयोग करके dict का उपयोग कर सकते हैं।

एफ.ई. एक भी निर्मित प्रकार KeyError यदि प्रकार dict में नहीं है पैदा होगा

class IntegerProperty(int): 
    pass 

class StringProperty(str): 
    pass 

a, b = IntegerProperty('1'), StringProperty('string') 

def to_primitive(obj): 
    switch = {IntegerProperty: int, StringProperty: str} 
    return switch[type(obj)](obj) 

for x in (a, b): 
     print(to_primitive(x)) 

यदि एक से अधिक उपयोगकर्ता के प्रकार परिभाषित करने के लिए नक्शे यहाँ क्योंकि कुंजी के बजाय वस्तु के प्रकार isinstance जांच, है। इसलिए आपको प्रत्येक उपयोगकर्ता-परिभाषित प्रकार को स्विच dict पर स्पष्ट रूप से जोड़ना होगा।

एफ.ई.

class TextProperty(StringProperty): 
    pass 
switch = {IntegerProperty: int, StringProperty: str, TextProperty: str} 

से ऊपर हम भी TextProperty हालांकि switch करने के लिए नए TextProperty जोड़ लिया है StringProperty के उपवर्ग है। यदि आप ऐसा नहीं करना चाहते हैं तो हमें isinstance चेक से कुंजी प्राप्त करनी होगी।
यहां यह कैसे करें;

class IntegerProperty(int): 
    pass 

class StringProperty(str): 
    pass 

class TextProperty(StringProperty): 
    pass 

a, b, c = IntegerProperty('1'), StringProperty('string'), TextProperty('text') 

def to_primitive(obj): 
    switch = {IntegerProperty: int, StringProperty: str} 
    key = filter(lambda cls: isinstance(obj, cls), switch.keys()) 
    if not key: 
     raise TypeError('Unknown type: {}'.format(repr(obj))) 
    key = key[0] 

    return switch[key](obj) 

for x in (a, b, c): 
     print(to_primitive(x)) 
संबंधित मुद्दे

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