-
Notifications
You must be signed in to change notification settings - Fork 116
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
Can not add new items for nested object via PATCH request with "Content-Type" : "multipart/form-data" ! #106
Comments
Sending patch request with Content-Type multipart/form-data can be achieved like belowYou can send the value for "invoice_services" field as [{"id": 17,"description_of_service": "TV servicing","quantity": "1.00","unit": "h","price": "1000.00","discount_percent": "6.00","vat_percent": "0.00","invoice": 9},{"description_of_service": "AC servicing","quantity": "1.00","unit": "h","price": "1000.00","discount_percent": "6.00","vat_percent": "0.00", "invoice": 9}] Here, the whole nested json dict object will be passed as a string value which will contain exact same structure if you send it via Content-Type application/json. It'll be sent as a string value in the backend. In backend, you need to parse this string value to a list of dict object then you can replace the fields value with the parsed data. It can be parsed like this,
Now, you need to convert the form-data request to a dict object
And finally, you need to update the invoice_services field's value with the above parsed data
Congratulations!!! You've got your desired json request data using form-data with file/image which can be sent to serializers as a request data. |
@xalien10 I don't understated your solution |
I've run into the same issue recently and its was pretty much a major roadblock for the application I'm developing. I hacked together a temporary solution that appears to get the results I want, albeit not in what I consider to be a good way. having said that, I figure that it might help somebody else or perhaps someone will be inspired and come up with an improvement based on what I have. Its not a general use solution as it assumes that the related models use an auto incremented id but again, might be useful to somebody until a better fix is added. I added the following code to my serializer. The differences between my code and the original writable nested serializer code are marked by ########### `
` |
@uripeled2 I just used the string which actually contained string instead of json object in formdata in postman. After receiving the request I was using python's eval to convert the string to appropriate data structure in python. |
Hi! Thank you for raising the issue. P.S.
I would like to warn you that it never should be done this way. https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html |
The use-case of form-data type requests in drf is very often that you want to be able to handle sending a file in your request. In order to not have to handle images and data separately, which could dramatically increase the amount of requests your api has to handle, it becomes useful to handle data also in the same request. This isn't ordinarily a problem as Django model serializers support this use out of the box. drf-writable-nested is a package that builds on top of django's default model serializers and allows you to also create AND update related objects in one endpoint. The whole benefit of this is supposed to be to prevent having to make multiple api calls. Having said that, it seems fairly straightforward that since writable nested fully supports nested created AND update operations for json requests and works perfectly fine for nested create operations for form-data requests, it should also support nested update operations for form-data requests because otherwise, we're back to the issue of having to handle such things using multiple requests to perform what would ideally be done in one. Its unclear what kind of documentation is needed to encourage a package to fully solve the problem it was literally designed to solve. Its not obvious that form-data is designed not to support nesting since all http request clients seem to support support sending form-data in the format |
As |
It is a bit tricky that it seems after a high-level overview.
I think that the best what we can do is to provide some samples of how it could be done on the application layer. @C4UT1ON @xalien10 P.S.
|
that is indeed tricky...i'll have to do some more research |
After I did some digging on version 0.7.0, from drf_writable_nested import WritableNestedModelSerializer, NestedUpdateMixin
class NestedFormDataModelSerializer(WritableNestedModelSerializer):
def update(self, instance, validated_data):
relations, reverse_relations = self._extract_relations(validated_data)
# Create or update direct relations (foreign key, one-to-one)
self.update_or_create_direct_relations(
validated_data,
relations,
)
# Update instance
instance = super(NestedUpdateMixin, self).update(
instance,
validated_data,
)
# The only difference is switch these 2 methods order. Delete existing instance(s) first then update & add later.
self.delete_reverse_relations_if_need(instance, reverse_relations)
self.update_or_create_reverse_relations(instance, reverse_relations)
instance.refresh_from_db()
return instance |
I've come across the same issue when attempting to add new items for a nested object using a PATCH request with "Content-Type" set to "multipart/form-data". After investigating and experimenting, I discovered that the multipart/form-data format doesn't provide a straightforward way to represent nested objects with new items. One possible workaround for this issue is to modify the API design to accept the nested object's items as individual fields within the request. For example, instead of sending an array of nested object items, you can send the items as separate fields with distinct names, such as "nested_object_1", "nested_object_2", and so on. On the server side, you can then handle these fields and construct the nested object with the new items programmatically. This approach allows you to work within the constraints of the multipart/form-data format. However, it's worth noting that if you have control over the API design, it may be more straightforward to use JSON-based payloads instead of multipart/form-data for complex nested objects. JSON provides a more natural representation for nested structures, making it easier to handle updates and additions. I hope this information helps others facing the same challenge. If anyone has found alternative solutions or workarounds, please feel free to share them as well. |
I can add new item via patch request with Content-Type application/json
Now If I want to do the same thing with Content-Type multipart/form-data I can't do that
Any suggestions ?
@ruscoder
The text was updated successfully, but these errors were encountered: