CharField should not accept collections as valid input by sloria · Pull Request #3394 · encode/django-rest-framework (original) (raw)
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Conversation12 Commits1 Checks0 Files changed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
[ Show hidden characters]({{ revealButtonHref }})
This issue came up on the marshmallow issue tracker (marshmallow-code/marshmallow#231), so I thought I'd pass it along here.
It seems incorrect for CharField
to take numbers and collections as valid input.
Code to reproduce
from django.conf import settings settings.configure(INSTALLED_APPS=['rest_framework']) import django django.setup() from rest_framework import serializers as ser from rest_framework.exceptions import ValidationError
field = ser.CharField()
inputs = ( 42, 42.0, {}, [] )
for val in inputs: try: field.run_validation(val) except ValidationError as err: print(err.detail[0])
Expected
Validation fails with messages like "{} is not a valid string."
.
Actual
Numbers and collections pass validation.
I'm not quite sure why the py3x-django18 builds are failing; I can look into it further if you decide this change is a good idea.
I don't think I mind us coercing numbers to string representations. Collection types should prob fail tho.
What is the rationale for allowing numbers? Any time a client passes a number to a string field, it is most likely due to user or client error and should be treated as such. The client should be responsible for "stringifying" any numerical input.
^ Same goes for booleans passed to a string field.
I agree with triggering an error when a collection is passed in as a string.
What is the rationale for allowing numbers?
I'm -0 on not allowing numbers mostly because that's expected functionality at the moment and changing this would break backwards compatibility. We even had a test to ensure that numbers were coerced properly.
It's also useful to note that there may be renders out there which try their best to coerce string input to the right type, so numbers would become a numeric type (decimal, probably) instead of staying as strings. We allow for the reverse case (numbers passed in as strings to number-type fields), so I don't understand why we would want to disallow this.
We allow for the reverse case (numbers passed in as strings to number-type fields), so I don't understand why we would want to disallow this.
Indeed, most of simple fields accept strings as input. The fields' deserialization logic, however, is responsible for deciding which string inputs are valid (e.g. Boolean
accepts "true"
but not "glue"
). That logic is also responsible for deciding which Python types are valid (e.g. Dict
only accepts dict
; Boolean
doesn't accept dict
).
I lean slightly toward disallowing numbers as inputs to String
. That said, I don't feel that strongly about it, and it's probably not worth breaking backwards compat for this change. Let me know how to proceed.
At least they should be treated as individually. The case for one pull request is unambiguous, the case for the other less so.
I'd like to see this be configurable at least. I would imagine passing anything other than a string to a CharField is usually indicative of user error.
I would imagine passing anything other than a string to a CharField is usually indicative of user error.
Possibly, tho "Generous on input, strict on output" could also be a valid rule of thumb for us to use here.
tomchristie changed the title
CharField should not accept numbers and collections as valid input CharField should not accept collections as valid input
Retitling to reflect the resolution.