I am building a Django+DRF/React
app (simple blog app) and i am facing difficulties saving nested images
Model Structure
- Model:
- Post
- Children:
- details: ContentType Model ( DRF: save is successfull )
- images: ContentType Model ( DRF : save is not successfull )
Process
Send images from
<input type="file" multiple />
Process data through
FormData
Catch
request.data
and process itclass PostFormView(generics.RetrieveUpdateDestroyAPIView): queryset = Post._objects.is_active() serializer_class = PostModelSerializer permission_classes = (IsOwnerOr401,) parser_classes = (parsers.MultiPartParser,parsers.JSONParser, parsers.FormParser, parsers.FileUploadParser) lookup_field = 'slug' lookup_url_kwarg = 'slug' def get_queryset(self): return super().get_queryset().annotate(**sharedAnnotations(request=self.request)) def update(self, request, *args, **kwargs): data = request.data _images = data.getlist('images') images = [] for _ in _images: if isinstance(_, dict): images.append(images) continue images.append({'image': _, 'object_id': self.get_object().pk, 'content_type': self.get_object().get_content_type().pk}) data['images'] = images print(data) partial = kwargs.pop('partial', False) instance = self.get_object() serializer = self.get_serializer(instance, data=data, partial=partial) serializer.is_valid(raise_exception=True) self.perform_update(serializer) if getattr(instance, '_prefetched_objects_cache', None): instance._prefetched_objects_cache = {} return Response(serializer.data)
Save images (FAIL):
class MediaModelSerializer(ContentTypeModelSerializer): # inherits object_id & content_type fields just to avoid writing them over and over alongside (create & update fns) class Meta: model = Media fields='__all__' class PostModelSerializer(WritableNestedModelSerializer): is_active = serializers.BooleanField(default=True) path = serializers.HyperlinkedIdentityField( view_name="api:post-detail", lookup_field='slug') images = MediaModelSerializer(many=True) details = DetailModelSerializer(required=False, many=True) # annotated fields is_author = serializers.BooleanField(read_only=True, default=False) class Meta: model = Post fields = '__all__' read_only_fields = ['is_locked', 'slug', 'user', 'is_author'] def create(self, validated_data): return super().create(validated_data) def update(self, instance, validated_data): return super().update(instance, validated_data)
The
print(data)
statement fromPostFormView.update(self, request, *args, **kwargs)
(after manipulation) returns this:<QueryDict: {'id': ['8'], ..., 'images': [[{'image': <InMemoryUploadedFile: bmw_3.jpeg (image/jpeg)>, 'object_id': 8, 'content_type': 20}, {'image': <InMemoryUploadedFile: bmw_2.jpeg (image/jpeg)>, 'object_id': 8, 'content_type': 20}, {'image': <InMemoryUploadedFile: bmw_1.jpeg (image/jpeg)>, 'object_id': 8, 'content_type': 20}]]}>
Server returns
400_BAD_REQUEST
because images were not passed toPostModelSerializer
{"images":["This field is required."]}
i've been facing this issue for 3 days and i can't wrap my head around the root cause.
Thank you for your help.
i have been looking all over the internet but i could not find any anwsers so i had to go this way
I have removed the processing part from
PostFormView.update(...)
and accessed theimages
directly in thecreate
&update
methods of theModelSerializer
. I'll figure out later on how to handle removing these imagesHere's the code:
If anyone has faced this issue before and managed to resolve it, please post your answer below.
Thank you !