Django Rest Framework Validation Order Issue

69 views
Skip to first unread message

Brent O'Connor

unread,
Jun 26, 2020, 6:08:03 PM6/26/20
to Django REST framework
I created an example project to illustrate this issue, but basically if you have custom validation logic on a serializer and the data has a field that isn't valid, then the errors raised are only the field level errors and not the custom validation logic errors. This ends up being a bad user experience because the user can fix the field error and then when post another request they can end up getting errors thrown in the custom validation. I'm thinking this might need to be an issue added the DRF project on Github, but thought I would check here first. Please see the project example for more details.

Carl Nobile

unread,
Jun 27, 2020, 1:25:22 PM6/27/20
to django-res...@googlegroups.com
It is possible to turn off the built infield errors. The empty list essentially turns off al field validation. If there are multiple and you don't want all turned off you would need to specify them yourself.

Class SomeSeializer(...):

    class Meta:
        extra_kwargs = { 
           'field_name': {'validators': []},
           }


On Fri, Jun 26, 2020 at 6:08 PM Brent O'Connor <epic...@gmail.com> wrote:
I created an example project to illustrate this issue, but basically if you have custom validation logic on a serializer and the data has a field that isn't valid, then the errors raised are only the field level errors and not the custom validation logic errors. This ends up being a bad user experience because the user can fix the field error and then when post another request they can end up getting errors thrown in the custom validation. I'm thinking this might need to be an issue added the DRF project on Github, but thought I would check here first. Please see the project example for more details.

--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-fram...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-rest-framework/121a7ebe-4b34-4197-be60-1178730361f7o%40googlegroups.com.


--
-------------------------------------------------------------------------------
Carl J. Nobile (Software Engineer)
carl....@gmail.com
-------------------------------------------------------------------------------

Brent O'Connor

unread,
Jun 27, 2020, 4:05:36 PM6/27/20
to django-res...@googlegroups.com
Unfortunately, that doesn't really solve the issue because you want field-level validation to run because you want to make sure that valid numbers, etc. are being sent to the API.

Carl Nobile

unread,
Jun 27, 2020, 4:34:05 PM6/27/20
to django-res...@googlegroups.com
Then write your custom validation as a field validator and put them all in the list in the order you want them to fire off in or you could include the field validator checks into your custom validation method.
The problem is that DRF can only implement what the common cases are, not all the edge cases people may need, but the hooks are there in the code to customize it the way you want.


Brent O'Connor

unread,
Jun 29, 2020, 11:34:42 AM6/29/20
to Django REST framework
I understand that you can go about solving it this way, but it seems like a lot of extra work when it just works the way you would expect on a Django ModelForm. I'm guessing this isn't possible for it to "just work", so I might end up making an issue in the DRF project.


On Saturday, June 27, 2020 at 3:34:05 PM UTC-5, Carl Nobile wrote:
Then write your custom validation as a field validator and put them all in the list in the order you want them to fire off in or you could include the field validator checks into your custom validation method.
The problem is that DRF can only implement what the common cases are, not all the edge cases people may need, but the hooks are there in the code to customize it the way you want.


On Sat, Jun 27, 2020 at 4:05 PM Brent O'Connor <br...@epicserve.com> wrote:
Unfortunately, that doesn't really solve the issue because you want field-level validation to run because you want to make sure that valid numbers, etc. are being sent to the API.

On Sat, Jun 27, 2020 at 12:25 PM Carl Nobile <carl....@gmail.com> wrote:
It is possible to turn off the built infield errors. The empty list essentially turns off al field validation. If there are multiple and you don't want all turned off you would need to specify them yourself.

Class SomeSeializer(...):

    class Meta:
        extra_kwargs = { 
           'field_name': {'validators': []},
           }


On Fri, Jun 26, 2020 at 6:08 PM Brent O'Connor <epic...@gmail.com> wrote:
I created an example project to illustrate this issue, but basically if you have custom validation logic on a serializer and the data has a field that isn't valid, then the errors raised are only the field level errors and not the custom validation logic errors. This ends up being a bad user experience because the user can fix the field error and then when post another request they can end up getting errors thrown in the custom validation. I'm thinking this might need to be an issue added the DRF project on Github, but thought I would check here first. Please see the project example for more details.

--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+unsub...@googlegroups.com.


--
-------------------------------------------------------------------------------
Carl J. Nobile (Software Engineer)
carl....@gmail.com
-------------------------------------------------------------------------------

--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+unsub...@googlegroups.com.

Brent O'Connor

unread,
Jun 30, 2020, 11:26:25 AM6/30/20
to Django REST framework
Carl, I created another branch on my example project that solves this issue by overriding two DRF methods (to_internal_value and run_validation). I'm probably going to create an issue in DRF that suggests that a solution like this gets added.


On Saturday, June 27, 2020 at 3:34:05 PM UTC-5, Carl Nobile wrote:
Then write your custom validation as a field validator and put them all in the list in the order you want them to fire off in or you could include the field validator checks into your custom validation method.
The problem is that DRF can only implement what the common cases are, not all the edge cases people may need, but the hooks are there in the code to customize it the way you want.


On Sat, Jun 27, 2020 at 4:05 PM Brent O'Connor <br...@epicserve.com> wrote:
Unfortunately, that doesn't really solve the issue because you want field-level validation to run because you want to make sure that valid numbers, etc. are being sent to the API.

On Sat, Jun 27, 2020 at 12:25 PM Carl Nobile <carl....@gmail.com> wrote:
It is possible to turn off the built infield errors. The empty list essentially turns off al field validation. If there are multiple and you don't want all turned off you would need to specify them yourself.

Class SomeSeializer(...):

    class Meta:
        extra_kwargs = { 
           'field_name': {'validators': []},
           }


On Fri, Jun 26, 2020 at 6:08 PM Brent O'Connor <epic...@gmail.com> wrote:
I created an example project to illustrate this issue, but basically if you have custom validation logic on a serializer and the data has a field that isn't valid, then the errors raised are only the field level errors and not the custom validation logic errors. This ends up being a bad user experience because the user can fix the field error and then when post another request they can end up getting errors thrown in the custom validation. I'm thinking this might need to be an issue added the DRF project on Github, but thought I would check here first. Please see the project example for more details.

--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+unsub...@googlegroups.com.


--
-------------------------------------------------------------------------------
Carl J. Nobile (Software Engineer)
carl....@gmail.com
-------------------------------------------------------------------------------

--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+unsub...@googlegroups.com.

Brent O'Connor

unread,
Jun 30, 2020, 5:51:28 PM6/30/20
to Django REST framework
For anyone that might come across this thread, I went ahead and created an issue for this on Github.

Carl Nobile

unread,
Jun 30, 2020, 6:42:08 PM6/30/20
to django-res...@googlegroups.com
Brent, overriding the 'to_internal_value' method is normal and encouraged, however, the 'run_validation' shouldn't generally be overridden, what you can override is the 'validate' method which is called by 'run_validation'.
~Carl

--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-fram...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-rest-framework/ea8a9b5d-a671-42b4-9cee-043f28f8efa3o%40googlegroups.com.

Brent O'Connor

unread,
Jun 30, 2020, 6:59:33 PM6/30/20
to django-res...@googlegroups.com
I guess my point is that I don't feel like I should have to override anything and this should be DRF's default behavior. 🙂 Thank you for pointing out that `validation` should be the method that should be used. 

Özgür Akçalı

unread,
Jul 1, 2020, 6:45:00 AM7/1/20
to Django REST framework
Though you can not achieve what you want by just overriding validate, and not overriding run_validation

This would be a major change in DRF though, as with the current behavior, when you write your validate method, you can assume other validations passed, so I imagine changing this behavior as default now would break a lot of existing code. I think this would fit better as an optional addition, maybe with a configuration option on existing serializer classes, or with a different set of serializer classes.


On Wednesday, July 1, 2020 at 1:59:33 AM UTC+3, Brent O'Connor wrote:
I guess my point is that I don't feel like I should have to override anything and this should be DRF's default behavior. 🙂 Thank you for pointing out that `validation` should be the method that should be used. 

On Tue, Jun 30, 2020, 5:42 PM Carl Nobile <carl....@gmail.com> wrote:
Brent, overriding the 'to_internal_value' method is normal and encouraged, however, the 'run_validation' shouldn't generally be overridden, what you can override is the 'validate' method which is called by 'run_validation'.
~Carl

On Tue, Jun 30, 2020 at 5:51 PM Brent O'Connor <epic...@gmail.com> wrote:
For anyone that might come across this thread, I went ahead and created an issue for this on Github.

On Friday, June 26, 2020 at 5:08:03 PM UTC-5, Brent O'Connor wrote:
I created an example project to illustrate this issue, but basically if you have custom validation logic on a serializer and the data has a field that isn't valid, then the errors raised are only the field level errors and not the custom validation logic errors. This ends up being a bad user experience because the user can fix the field error and then when post another request they can end up getting errors thrown in the custom validation. I'm thinking this might need to be an issue added the DRF project on Github, but thought I would check here first. Please see the project example for more details.

--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+unsub...@googlegroups.com.


--
-------------------------------------------------------------------------------
Carl J. Nobile (Software Engineer)
carl....@gmail.com
-------------------------------------------------------------------------------

--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+unsub...@googlegroups.com.

Özgür Akçalı

unread,
Jul 1, 2020, 7:02:53 AM7/1/20
to Django REST framework
I think you also need to override run_validators method in your example project for it to work as you expect, just like you did for to_internal_value. If a validation error is raised fom run_validators method, validate method is not called, so you can not aggregate any possible errors raised from validation checks in that method.

Also, with this flow, you should take care not to raise validation errors in your custom validate methods one by one, but aggregate them and raise them or return them together there as well.

Brent O'Connor

unread,
Jul 1, 2020, 12:27:33 PM7/1/20
to Django REST framework
Hi Özgür,

I'm not sure if you saw it or not but I did come up with a solution in another branch (https://github.com/epicserve/drf-validation-issue/blob/fix-validation/pizzas/serializers.py) and I did end up overriding run_validation and to_internal_value. If I can find time, I think I'll look into putting my solution into a fork of DRF and just see what might break when I run tests. It doesn't seem like anything would break, but I'm not confident that is the case.
Reply all
Reply to author
Forward
0 new messages