django-restql: Creating a related object when using PATCH method raises a server error
Let’s say I have these models:
class Address(models.Model):
street = models.CharField()
city = models.CharField()
postcode = models.CharField()
class Person(models.Model):
address = models.ForeignKey('Address', null=True, blank=True, on_delete=models.SET_NULL)
... other fields ...
(note that all the fields in the Address model are required)
The address field is a NestedField in my serializer
class PersonSerializer(DynamicFieldsMixin, NestedModelSerializer):
address = NestedField(AddressSerializer, allow_null=True, required=False)
When I create a Person object with address being null and then want to add the address later using a PATCH method with some of the fields missing,
PATCH /api/person/1/
{
"address": {"street": "Main street 1"}
}
I get a server error.
File "E:\Documents\Work\hriis-crm\backend\.venv\lib\site-packages\rest_framework\serializers.py", line 200, in save
self.instance = self.update(self.instance, validated_data)
File "E:\Documents\Work\hriis-crm\backend\.venv\lib\site-packages\django_restql\mixins.py", line 985, in update
fields["foreignkey_related"]["writable"]
File "E:\Documents\Work\hriis-crm\backend\.venv\lib\site-packages\django_restql\mixins.py", line 756, in update_writable_foreignkey_related
obj = serializer.save()
File "E:\Documents\Work\hriis-crm\backend\.venv\lib\site-packages\rest_framework\serializers.py", line 178, in save
'You cannot call `.save()` on a serializer with invalid data.'
AssertionError: You cannot call `.save()` on a serializer with invalid data.
When I use a PUT method, I get a normal HTTP 400 response with validation messages.
{
"address": {
"city": [
"This field is required."
],
"postcode": [
"This field is required."
]
}
}
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 27 (12 by maintainers)
Commits related to this issue
- 🐛 Fix server error when using PUT/PATCH to create/update related objects - Fixes #211 — committed to yezyilomo/django-restql by yezyilomo 3 years ago
- 🐛Catch model constraint errors which led to server error - Fixes #211 — committed to yezyilomo/django-restql by yezyilomo 3 years ago
I didn’t know about this, thanks for the heads up, will definitely use it next time.
Yes that is the other way we were thinking of handling it.
I have the same thought as you. BUT, and you can try it with the repository I made. If you add raise_exception to the line I told you. I am not sure why, it returns a nice validation error and not the db integrity error.
Proof:
This is the error returned to the api client
I think when API user sends data which violates DB constraint that’s not devs fault, devs job is to make sure when something like this happen they tell API users what they have done wrong so that they can fix their input.
I have confirmed everything is rolled back if one step fails, You can use
'ATOMIC_REQUESTS': True,in DB configYeah, this is true, even if you don’t add
raise_exeption=Truethe exception will be raised the difference is that withraise_exeption=Trueyou getValidationError, and without it the serializer crushes.Thank you for pointing this out, I’ve managed to reproduce it, it’s definitely a bug, we should be raising validation error and not server error. I’m working on fixing it, if you have any information about the cause feel free to share it.