【问题标题】:Colander: how do I allow None values?滤锅:我如何允许 None 值?
【发布时间】:2016-11-12 01:59:21
【问题描述】:

假设我有一个简单的架构:

class MySchema(colander.MappingSchema):
    thing = colander.SchemaNode(colander.Int())

使用上面的架构,在尝试反序列化 {'thing': None} 时出现错误:

Invalid: {'thing': u'Required'}

看起来漏勺处理具有None 值的字段的方式与处理缺失字段的方式相同。我怎样才能解决这个问题并强制始终提供thing,但允许它是None

【问题讨论】:

    标签: python colander


    【解决方案1】:

    请考虑这个解决方案。

    import colander
    
    
    class NoneAcceptantNode(colander.SchemaNode):
        """Accepts None values for schema nodes.
        """
    
        def deserialize(self, value):
            if value is not None:
                return super(NoneAcceptantNode, self).deserialize(value)
    
    
    class Person(colander.MappingSchema):
        interest = NoneAcceptantNode(colander.String())
    
    
    # Passes
    print Person().deserialize({'interest': None})
    
    # Passes
    print Person().deserialize({'interest': 'kabbalah'})
    
    # Raises an exception
    print Person().deserialize({})
    

    【讨论】:

      【解决方案2】:

      None 值适用于反序列化,但您需要在架构中提供“缺失”参数:

      class MySchema(colander.MappingSchema):
          thing = colander.SchemaNode(colander.Int(), missing=None)
      

      http://docs.pylonsproject.org/projects/colander/en/latest/null.html#deserializing-the-null-value

      【讨论】:

      • 这无济于事:正如您链接的页面上的this table 中突出显示的那样,使用colander.null 仍会引发Invalid 异常。 colander.null 和缺失值对于滤锅来说几乎是一回事。我的问题是None 似乎也被视为相同,尽管我找不到有关此行为的任何文档。
      • 啊,好吧,看起来您实际上需要在架构中设置默认缺失值。我已更新我的答案以包含此内容。
      • 仍然不符合我的要求...使用missing=None 时,即使thing 不存在,它也会被添加并设置为None。如果thing 没有出现在我想要提高的数据中,则不会自动添加它。
      • 您希望引发错误?这不是已经发生了吗?
      • 我希望在thing 不存在时引发错误。如果存在thing(即使是None),我不希望引发错误。
      【解决方案3】:

      这是我正在使用的。我将空字符串映射到显式空值。如果 required 标志为真,则会引发无效错误。

      from colander import SchemaNode as SchemaNodeNoNull
      
      class _SchemaNode(SchemaNodeNoNull):
      
          nullable = True
      
          def __init__(self, *args, **kwargs):
              # if this node is required but nullable is not set, then nullable is
              # implicitly False
              if kwargs.get('missing') == required and kwargs.get('nullable') is None:
                  kwargs['nullable'] = False
              super(_SchemaNode, self).__init__(*args, **kwargs)
      
          def deserialize(self, cstruct=null):
              if cstruct == '':
                  if not self.nullable:
                      raise Invalid(self, _('Cannot be null'))
                  if self.validator:
                      self.validator(self, cstruct)
                  return None  # empty string means explicit NULL value
              ret = super(_SchemaNode, self).deserialize(cstruct)
              return ret
      

      另外,在处理查询字符串参数时,foo=,bar= 会变成:

      {
         "foo": "",
         "bar": ""
      }
      

      文字空值仅适用于 JSON 有效负载

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-06-21
        • 2020-12-29
        • 2015-12-18
        • 1970-01-01
        • 2015-06-29
        • 2017-12-06
        • 2022-09-27
        相关资源
        最近更新 更多