{"action":"created","issue":{"url":"https://api.github.com/repos/marshmallow-code/marshmallow/issues/367","labels_url":"https://api.github.com/repos/marshmallow-code/marshmallow/issues/367/labels{/name}","comments_url":"https://api.github.com/repos/marshmallow-code/marshmallow/issues/367/comments","events_url":"https://api.github.com/repos/marshmallow-code/marshmallow/issues/367/events","html_url":"https://github.com/marshmallow-code/marshmallow/issues/367","id":123943452,"number":367,"title":"RFC: Improved API for registering field validator methods","user":{"login":"sloria","id":2379650,"avatar_url":"https://avatars.githubusercontent.com/u/2379650?v=3","gravatar_id":"","url":"https://api.github.com/users/sloria","html_url":"https://github.com/sloria","followers_url":"https://api.github.com/users/sloria/followers","following_url":"https://api.github.com/users/sloria/following{/other_user}","gists_url":"https://api.github.com/users/sloria/gists{/gist_id}","starred_url":"https://api.github.com/users/sloria/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sloria/subscriptions","organizations_url":"https://api.github.com/users/sloria/orgs","repos_url":"https://api.github.com/users/sloria/repos","events_url":"https://api.github.com/users/sloria/events{/privacy}","received_events_url":"https://api.github.com/users/sloria/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/marshmallow-code/marshmallow/labels/enhancement","name":"enhancement","color":"84b6eb"},{"url":"https://api.github.com/repos/marshmallow-code/marshmallow/labels/feedback%20welcome","name":"feedback welcome","color":"009800"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-12-26T18:35:25Z","updated_at":"2015-12-27T06:02:41Z","closed_at":null,"body":"## Status quo\r\n\r\nValidator methods are registered by decorating them with `@validates('my_field_name')`.\r\n\r\n```python\r\nfrom marshmallow import fields, Schema, ValidationError, validates\r\n\r\nclass ItemSchema(Schema):\r\n    quantity = fields.Int()\r\n\r\n    @validates('quantity')\r\n    def validate_quantity(self, value):\r\n        if value > 30:\r\n            raise ValidationError('Quantity must not be greater than 30')\r\n```\r\n\r\n## Proposed API\r\n\r\nValidator methods are registered by decorating them with `@my_field.validator`.\r\n\r\n```python\r\nfrom marshmallow import fields, Schema, ValidationError\r\n\r\nclass ItemSchema(Schema):\r\n    quantity = fields.Int()\r\n\r\n    @quantity.validator\r\n    def validate_quantity(self, value):\r\n        if value > 30:\r\n            raise ValidationError('Quantity must not be greater than 30')\r\n```\r\n\r\n## Benefits\r\n\r\n- Less prone to user error (no magic strings).\r\n- Removes redundant code. Since `Field#validator()` decorator would just append to a field's `validators` attribute, there would be no need for [this code](https://github.com/marshmallow-code/marshmallow/blob/bad7e56cd5602daf4eea31ce3cb49f07a5d7a9ba/marshmallow/schema.py#L762-L800). \r\n- Better introspection of fields. Again, since `Field#validator()` appends to `Field#validators`, code that introspects fields (e.g. apispec) can find all of a field's validators in one place."},"comment":{"url":"https://api.github.com/repos/marshmallow-code/marshmallow/issues/comments/167385764","html_url":"https://github.com/marshmallow-code/marshmallow/issues/367#issuecomment-167385764","issue_url":"https://api.github.com/repos/marshmallow-code/marshmallow/issues/367","id":167385764,"user":{"login":"jmcarp","id":1633460,"avatar_url":"https://avatars.githubusercontent.com/u/1633460?v=3","gravatar_id":"","url":"https://api.github.com/users/jmcarp","html_url":"https://github.com/jmcarp","followers_url":"https://api.github.com/users/jmcarp/followers","following_url":"https://api.github.com/users/jmcarp/following{/other_user}","gists_url":"https://api.github.com/users/jmcarp/gists{/gist_id}","starred_url":"https://api.github.com/users/jmcarp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jmcarp/subscriptions","organizations_url":"https://api.github.com/users/jmcarp/orgs","repos_url":"https://api.github.com/users/jmcarp/repos","events_url":"https://api.github.com/users/jmcarp/events{/privacy}","received_events_url":"https://api.github.com/users/jmcarp/received_events","type":"User","site_admin":false},"created_at":"2015-12-27T06:02:41Z","updated_at":"2015-12-27T06:02:41Z","body":"> Less prone to user error (no magic strings).\r\n\r\n:guitar: "}}