Issue
I’m trying to create a view where I can upload images at to a single model which has a foreign key to another model. The below given API works but however it only uploads 1 image. What am I doing wrong that it only takes the first image from the list and uploads in the media folder?
models.py
class RoofImages(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
job = models.ForeignKey(JobDetails, on_delete=models.PROTECT)
image = models.ImageField(upload_to=current_user_id)
image_type = models.CharField(max_length=15, choices=ROOF_VIEW_TYPES)
helpers.py
def modify_input_for_multiple_files(user, job, image, image_type):
image_dict = {}
image_dict['user'] = user
image_dict['job'] = job
image_dict['image'] = image
image_dict['image_type'] = image_type
return image_dict
views.py
class RoofImagesView(APIView):
serializer_class = RoofImagesSerializer
parser_classes = (MultiPartParser, FormParser)
def post(self, request, *args, **kwargs):
user = Token.objects.get(key=request.auth.key).user
job = request.data['job']
images = dict((request.data).lists())['image']
image_type = request.data['image_type']
flag = True
arr = []
for img_name in images:
modified_data = modify_input_for_multiple_files(user.user_uid, job, img_name, image_type)
serializer = RoofImagesSerializer(data=modified_data)
if serializer.is_valid():
serializer.save()
arr.append(serializer.data)
else:
flag = False
if flag:
response_content = {
'status': True,
'message': 'Images uploaded successfully.',
'result': arr
}
return Response(response_content, status=status.HTTP_201_CREATED)
else:
response_content = {
'status': False,
'message': 'Unable to upload images.',
'result': serializer.errors
}
return Response(response_content, status=status.HTTP_400_BAD_REQUEST)
Below is example with response that it only uploads 1 image
Request screenshot with response
Solution
I think, in RoofImagesSerializer
you need to define the create
function.
def RoofImagesSerializer(serializers.ModelSerializer):
image_file = serializers.FileField(max_length = 1000000, write_only = True)
...
def create(self, validated_data):
image_uri = validated_data.pop("image_file")
roof_image = RoofImages(**validated_data)
roof_image.image = image_uri
roof_image.save()
return roof_image
And of course in modify_input_for_multiple_files
function, image
key should be changed into image_file
def modify_input_for_multiple_files(user, job, image, image_type):
image_dict = {}
image_dict['user'] = user
image_dict['job'] = job
image_dict['image_file'] = image # here I changed the key
image_dict['image_type'] = image_type
return image_dict
And also the logic in for
loop is not correct. I think if flag
statement should be out of the for
loop.
def post(self, request, *args, **kwargs):
...
flag = True
arr = []
for img_name in images:
modified_data = modify_input_for_multiple_files(user.user_uid, job, img_name, image_type)
serializer = RoofImagesSerializer(data=modified_data)
if serializer.is_valid():
serializer.save()
arr.append(serializer.data)
else:
flag = False
# here I changed
if flag:
response_content = {
'status': True,
'message': 'Images uploaded successfully.',
'result': arr
}
return Response(response_content, status=status.HTTP_201_CREATED)
else:
response_content = {
'status': False,
'message': 'Unable to upload images.',
'result': serializer.errors
}
return Response(response_content, status=status.HTTP_400_BAD_REQUEST)
Hope it could help.
Answered By – David Lu
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0