2

I have a field in my model which is required in the resource body while creating the resource (POST) and is not passed in the request body(will be passed along with URL) while updating the resource (PUT).

I have created my marshmallow model:

class DummySchema():
   field_1 = fields.Str(required=True)
   field_2 = fields.Id()

If I leave field_1 to required=True, I get the following error on PUT :

{
    "message": {
        "field_1": [
            "Missing data for required field."
        ]
    }
}

I could leave it required in the model, but that would mean it would cause a problem in POST request.

Is there a way I could set the field as optional, but set it required for my POST request so that I can perform my validation?

Foo Bar
  • 71
  • 1
  • 5
  • If it is an ID field, then you might be better off letting the database create it. That's the typical pattern. Make it not required and `dump_only`. On POST, it is created in DB and returned in the response. On PUT, it is required as path parameter and used to fetch the item in DB. – Jérôme Apr 22 '19 at 20:10
  • It's a unique id created by an external db, which I need in my application. So I needed a way I could ensure it's required in the request body while creation, but is not in updation (as the id will be sent in the url) – Foo Bar Apr 23 '19 at 21:16
  • In this case, you should use PUT for both creation and update, and pass the ID as path parameter. https://stackoverflow.com/a/630475/4653485 – Jérôme Apr 24 '19 at 07:48

2 Answers2

4

I think I should've read the documentation thoroughly before :(

I could set a field as partial, so when it'll do validation marshmallow would skip the field

data, errors = DummySchema().load({'field_2': 42}, partial=('field_1',))

REF: https://marshmallow.readthedocs.io/en/2.x-line/quickstart.html#validation

Foo Bar
  • 71
  • 1
  • 5
0

If you want to use it for /POST request then this field can be added in dump_only list. This can also be used for /PUT request.

class StrategySchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Strategy
        sqla_session = db.session
        ordered = True
        load_instance = True
        dump_only = (  # read-only
            "id", 
            "created_by",
            "created_by_id",
            "created_at",
            "updated_at",
        )

dump_only means:

  • Consider these fields only while dumping a model to json (deserialization)
  • ignore it while loading a model from json
  • read-only fields in other words