marshmallow-code / marshmallow-code/marshmallow

Allow conditionally disabling fields

Open
#1,953 1 comment 0 reactions 0 assignees View on GitHub
polymorphism
Dominant language
Python
Stars
7.2k
Forks
738
Avg merge
1d 23h
Merged PRs (30d)
7

Description

I have this schema:

```py
class RequestAccessSchema(mm.Schema):
request_cern_access = fields.Bool(load_default=False, data_key='cern_access_request_cern_access')
birth_date = fields.Date(load_default=None, data_key='cern_access_birth_date',
validate=validate_with_message(lambda x: x <= date.today(),
'The specified date is in the future'))
nationality = fields.String(load_default='', data_key='cern_access_nationality')
birth_place = fields.String(load_default='', data_key='cern_access_birth_place')
by_car = fields.Bool(load_default=False, data_key='cern_access_by_car')
license_plate = fields.String(data_key='cern_access_license_plate', load_default='')

@validates_schema
def validate_everything(self, data, **kwargs):
# This ugly mess is needed since we can't skip fields conditionally...
if not data['request_cern_access']:
return
required_fields = {'birth_date', 'nationality', 'birth_place'}
if data['by_car']:
required_fields.add('license_plate')
errors = {}
for field in required_fields:
if not data[field]:
errors[self.fields[field].data_key] = ['This field is required.']
if data['by_car'] and data['license_plate']:
try:
validate.And(
validate.Length(min=3),
validate.Regexp(r'^[0-9A-Za-z]+([- ][ ]*[0-9A-Za-z]+)*$')
)(data['license_plate'])
except ValidationError as exc:
errors.setdefault(self.fields['license_plate'].data_key, []).extend(exc.messages)
if errors:
raise ValidationError(errors)
```

Depending on the bool fields in there, the rest of the data is either completely ignored (I set it to falsy values in a `post_load` function) or required (with some validation needed). It would be really nice if there was some way to disable fields during parse time; that way I could simply make them required and specify the validators declaratively, instead of having to fall back to this abomination up there.

If you have any other ideas on how this could be done without the mess above, maybe even using features already present in marshmallow, please let me know! :)

Contributor guide

Open the contributing guide

Research direction

Start with the RequestAccessSchema, its validates_schema method, and the post_load behavior described in the issue. Review how marshmallow fields, required values, validators, and conditional parsing currently interact; the work is done when fields can be declaratively disabled or required based on the boolean fields without the manual validation logic shown.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.