如果我有来自GET或POST请求的一些(字符串)值与关联的Property
个实例,一个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)
例如,如果有办法从int
获取IntegerProperty
类,从bool
等获得BooleanProperty
类,则可以完成工作
就我所见,ndb元数据API并没有真正解决这个问题;但get_representations_of_kind
我可以减少案件数量。
答案 0 :(得分:2)
您可以使用dict
在用户定义的类型与内置类型之间进行映射,方法是使用对象的type
作为键,将内置类型作为值。
F.e。
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
检查,如果类型不在,则会出现多个用户定义类型映射到单个内置类型KeyError
dict
。因此,您必须将每个用户定义的类型显式添加到交换机dict
。
F.e。
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))
答案 1 :(得分:1)
有一个名为WTForms的Python软件包对此非常有用,并且通常使表单处理成为一种更愉快的体验。
这是一个非常简单的例子:
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()
会自动将POST数据转换为表单指定的数据类型。因此f.text.data
将是一个字符串,而f.n.data
将是一个整数。
它还可以优雅地处理无效数据。如果用户输入整数字段的字母,则f.n.data
将为None
。您还可以指定容易合并到网页中的错误消息。
WTForms从表单处理中获取了大量的苦差事!