【问题标题】:Can webargs / Marshmallow in Python modify a field, not just validate it?Python 中的 webargs / Marshmallow 可以修改字段,而不仅仅是验证它吗?
【发布时间】:2018-04-06 22:20:11
【问题描述】:

我正在使用带有 flask-restful 和 webargs 的 Flask(它使用 Marshmallow 作为其后端)。目前,我可以通过以下方式提取我想要的字段:

class AddGroup(Resource):
    args = {
        'name': fields.Str(missing=None),
        'phone': fields.Str(missing=None),
    }

    @use_args(args)
    def get(self, args):
        name = args['name'].strip()
        # ... some GET-related code ...

    @use_args(args)
    def post(self, args):
        name = args['name'].strip()
        # ... some POST-related code ...

到目前为止一切顺利。但我真正想做的是确保args['name'] 进入各种方法(“post”、“get”等),其中的空格已经被剥离,所以我不必手动处理每个变量时间。 (去除空格只是一个例子——它可能是其他一些简单或复杂的转换)

有没有办法(通过覆盖 String 字段、定义我自己的字段或其他方式)允许在 args 到达类方法之前对其进行预处理?

【问题讨论】:

    标签: python flask flask-restful marshmallow webargs


    【解决方案1】:

    由于webargs 使用marshmallow 制作架构,您可以使用pre_loadpost_load。在棉花糖的文档中有一个“slugify”字符串的例子:

    from marshmallow import Schema, fields, pre_load
    
    class UserSchema(Schema):
        name = fields.Str()
        slug = fields.Str()
    
        @pre_load
        def slugify_name(self, in_data, **kwargs):
            in_data['slug'] = in_data['slug'].lower().strip().replace(' ', '-')
            return in_data
    
    schema = UserSchema()
    result = schema.load({'name': 'Steve', 'slug': 'Steve Loria '})
    result['slug']  # => 'steve-loria'
    

    您可以在此处查看详细文档:https://marshmallow.readthedocs.io/en/latest/extending.html#pre-processing-and-post-processing-methods

    【讨论】:

      【解决方案2】:

      您可以使用以下自定义字段类(作为组合):

      from marshmallow import fields
      
      
      class Trim(fields.Field):
          def __init__(self, inner, *args, **kwargs):
              self.inner = inner
              super().__init__(*args, **kwargs)
      
          def _bind_to_schema(self, field_name, parent):
              super()._bind_to_schema(field_name, parent)
              self.inner._bind_to_schema(field_name, parent)
      
          def _deserialize(self, value, *args, **kwargs):
              value = value.strip()
              return self.inner._deserialize(value, *args, **kwargs)
      
          def _serialize(self, *args, **kwargs):
              return self.inner._serialize(*args, **kwargs)
      

      使用示例:

      from marshmallow import Schema, fields
      
      class SomeSchema(Schema):
          name = Trim(fields.String(), validate=validate.Length(max=100))
          email = Trim(fields.Email(), required=True)
      

      来自here的想法

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-19
        • 1970-01-01
        • 1970-01-01
        • 2011-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多