0

Given that :

class BGPcommunitiesElasticSchema(marshmallow.Schema):
    comm_name = marshmallow.fields.Str(required=True)
    comm_value = marshmallow.fields.Str(required=True, )
    dev_name = marshmallow.fields.Str(required=True)
    time_stamp = marshmallow.fields.Integer(missing=time.time())

    @marshmallow.validates('comm_value')
    def check_comm_value(self, value):
        if value.count(":") < 1:
            raise marshmallow.ValidationError("a BGP community value should contain at least once the colon char")
        if value.count(":") > 2:
            raise marshmallow.ValidationError("a BGP community value should contain no more than two colon chars")

    # @marshmallow.pre_dump
    # def rename_comm_value(self, data):
    #     return data['comm_value'].replace(":","_")

How can I manipulate the field comm_value before serializing it ?

The field comm_value is a string for example 1234:5678 and I would like to convert it to 1234_5678.

Could you please advise on how to achieve that ?

PS. pre_dump looks the right way of doing it, but I am not sure since it is my first day using marshmallow

nskalis
  • 2,232
  • 8
  • 30
  • 49

2 Answers2

1

pre_dump can do what you want, but I would use a class method instead:

class BGPcommunitiesElasticSchema(marshmallow.Schema):
    comm_name = marshmallow.fields.Str(required=True)
    comm_value = marshmallow.fields.Method("comm_value_normalizer", required=True)
    dev_name = marshmallow.fields.Str(required=True)
    time_stamp = marshmallow.fields.Integer(missing=time.time())


    @marshmallow.validates('comm_value')
    def check_comm_value(self, value):
        if value.count(":") < 1:
            raise marshmallow.ValidationError("a BGP community value should contain at least once the colon char")
        if value.count(":") > 2:
            raise marshmallow.ValidationError("a BGP community value should contain no more than two colon chars")

    @classmethod
    def comm_value_normalizer(cls, obj):
        return obj.comm_value.replace(":", "_")

You could also create your own comm_value_normalized attribute that way if you want the original "comm_value" to remain untouched.

dizzyf
  • 3,263
  • 19
  • 29
  • if you have time could you please advise also on https://stackoverflow.com/questions/44166325/marshmallow-convert-dict-to-tuple i am wondering if that would be possible :) – nskalis May 24 '17 at 18:57
1

Looks like you want to work with serialized object (dict) and the best place might be then post_dump

from marshmallow import Schema, post_dump
class S(marshmallow.Schema):
    a = marshmallow.fields.Str()
    @post_dump
    def rename_val(self, data):
        data['a'] = data['a'].replace(":", "_")
        return data

>>> S().dumps(dict(a="abc:123"))
MarshalResult(data='{"a": "abc_123"}', errors={})
naoko
  • 5,064
  • 4
  • 35
  • 28