Home > Software engineering >  flask-marshmallow validation on field data not working
flask-marshmallow validation on field data not working

Time:11-24

Hi I made my dto something like this

class MyRequestDto(ma.Schema):
    @pre_load
    def wrap_data(self, in_data, **kwargs):
        return {"rooms": in_data}


    rooms = ma.Dict(ma.String, ma.Dict(ma.Integer, ma.String))

and I want to send request something like this :

{   
    "1faf8f07-2977-180e-7bc2-b5adf8badasda": {"student_id":11210687,"room_id":"100"}
}

but getting error like this

{
    "rooms": {
        "1faf8f07-2977-180e-7bc2-b5adf8badasda": {
            "value": {
                "student_id": {
                    "key": [
                        "Not a valid integer."
                    ]
                },
                "room_id": {
                    "key": [
                        "Not a valid integer."
                    ]
                }
            }
        }
    }
}

What I can do to pass data correctly in the required format?

CodePudding user response:

Integer type supports cast.

From the documentation:

class marshmallow.fields.Integer(*, strict: bool = False, **kwargs)[source]
    An integer field.
    Parameters
            strict – If True, only integer types are valid. Otherwise, any value castable to int is valid.
            kwargs – The same keyword arguments that Number receives.

So try:

class MyRequestDto(Schema):
    @pre_load
    def wrap_data(self, in_data, **kwargs):
        return {"rooms": in_data}

    rooms = Dict(String, Dict(String, Integer))

It will automatically handle the str for room_id.

If you want to keep room_id as str then you need to define a Custom Field.

Example:

class CustomField(Field):
    def _serialize(self, value, attr, obj, **kwargs):
        if isinstance(value, (str, int)):
            return value
        raise ValidationError("Value is not int or str")

    def _deserialize(self, value, attr, data, **kwargs):
        if isinstance(value, (str, int)):
            return value
        raise ValidationError("Value is not int or str")


class MyRequestDto(Schema):
    @pre_load
    def wrap_data(self, in_data, **kwargs):
        return {"rooms": in_data}

    rooms = Dict(String, Dict(String, CustomField))
  • Related