-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
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 and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ModelSerializer uniqueness check crashes with OverflowError and that crash can not be prevented with field-level validation #7134
Comments
This has to do with how we append the django-rest-framework/rest_framework/fields.py Lines 978 to 979 in 373e521
This is especially unintuitive because we strip out the existing django-rest-framework/rest_framework/utils/field_mapping.py Lines 136 to 145 in 373e521
I am not aware of the consequences of changing the location of where that validator is injected into the list of validators. |
BTW I found this bug using https://github.com/kiwicom/schemathesis - definitely worth checking out if you're building any APIs that are described by Swagger / OpenAPI 👍 |
My gut response.. I'm inclined to change how we handle uniqueness checks, and somewhat follow Django's lead. Looking at I'm thinking we could leave the class MySerializer(ModelSerializer):
my_field = CharField(validators=[UniqueValidator(queryset=MyModel.objects.all())]) to class MySerializer(ModelSerializer):
class Meta:
validators = [
UniqueFieldValidator(queryset=MyModel.objects.all(), field_name='my_field'),
] By moving the uniqueness check to the serializer from the field, this would ensure that the max value validator is checked first. |
This may also just be an issue with the sqlite backend. https://code.djangoproject.com/ticket/27397 |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Checklist
master
branch of Django REST framework.Steps to reproduce
First: check Django behaviour
Given a simple Model with a single
IntegerField
, when working with SQLite (I'm running version 3.27 which is officially supported by Django) it is possible to generate an overflow error.Model:
Test:
Gives an
OverflowException
:However, using
MaxValueValidator
allows us to protect SQLite from this overflow. So if we change the model and test, then Django raises aValidationError
complaining thatvalue
is too large:Model:
Test:
In this way we can use Django to protect SQLite from the overflow - all is good at the Django level.
DRF behaviour
Now we make a
ModelSerializer
for this updated model with theMaxValueValidator
in place and test it with the large int:Expected behaviour
This test should pass. The DRF model serializer should raise a
ValidationError
that complains thatvalue
is too large, something like:Actual behaviour
However the test fails with an
OverflowError
which arises from the uniqueness check:Thoughts
(Ignore as appropriate)
It looks to me like the check for uniqueness happens before the field level validation that happens as a result of the
MaxValueValidator
because when I dump the field'svalidators
I get:This means that round-tripping the database happens before checking the max value. This is unexpected behaviour and I was surprised when I found it - I would expect as much validation as possible to take place before the database hit.
I also experimented with adding a field-level
validate_value()
function to the serializer, but it appears thatrun_validators()
happens before that is trigged, so it's no help in preventing the overflow.The text was updated successfully, but these errors were encountered: