django update profile image only if user has uploaded it

Viewed 78

When the user does not upload an image and saves the form I get the following error.

Internal Server Error: /user/profile/update
Traceback (most recent call last):
  File "\site-packages\django\utils\datastructures.py", line 76, in __getitem__
    list_ = super().__getitem__(key)
KeyError: 'img'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "\auth\users\views.py", line 63, in profile_update
    image = Image.open(request.FILES['img'].file)
  File "\site-packages\django\utils\datastructures.py", line 78, in __getitem__
    raise MultiValueDictKeyError(key)
django.utils.datastructures.MultiValueDictKeyError: 'img'
[16/Jun/2021 09:39:40] "POST /user/profile/update HTTP/1.1" 500 89309

I want to check the image is null then form does not need to do anything with the image, if the image is uplaoded then do some logic with it - upload it to an external api.

def profile_update(request):
    user = request.user
    print(user.user_face_img_md5)
    if request.method == 'POST':
        form = UpdateProfile(request.POST, instance=request.user)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            obj = form.save(commit=False)
            if request.FILES['img']:
                image = Image.open(request.FILES['img'].file)
                if image:
                    print("Updating image..")
                    #deleteImage(obj.user_face_img_md5)
                    #image_md5 = uploadImage(image)
            else:
                print("No image uploaded")
            print(image)
            obj.user_face_img_md5 = image_md5
            obj.save()
            messages.success(
                request, f'Account has been updated!')
            return redirect('profile')

    return render(request, 'users/profile_update.html', {'form': form})

I think that the error comes from request.FILES and saying that the key img is not there so I can use this to check if the image is uploaded. But maybe my implementation is wrong, I should check if the key exists in the dictionary.

Also, after checking if the image is uploaded, and if not - on form.save() it will save automatically only the fields that are tied with the model? because the image is a form field and not a model field.

class UpdateProfile(forms.ModelForm):
    email = forms.EmailField()
    img = forms.ImageField(label='img', required=False)

    class Meta:
        model = TbUser
        fields = [some fieLds]

update

def profile_update(request):
    user = request.user
    if request.method == 'POST':
        form = UpdateProfile(
            request.POST, request.FILES or None, instance=request.user,)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            obj = form.save(commit=False)
            print(request.POST.get('img'))
            if request.POST.get('img'):
                image = Image.open(request.FILES['img'].file)
                deleteImage(obj.user_face_img_md5)
                obj.user_face_img_md5 = uploadImage(image)
            else:
                print("No image uploaded")
            obj.save()
            messages.success(
                request, f'Account has been updated!')
            return redirect('profile')
    else:
        data = {
            'username': user.username,
            'email': user.email,
            'cellphone': user.cellphone,
            'empno': user.empno,
            'real_name': user.real_name,
            'nfc_id': user.nfc_id,
            'sex': user.sex,
            'role': user.role,
            'department': user.department,
        }
        form = UpdateProfile(initial=data)

    return render(request, 'users/profile_update.html', {'form': form, 'img_str': user.user_face_img_md5})
1 Answers

changing your:

 form = UpdateProfile(request.POST, instance=request.user)

to this:

form = UpdateProfile(request.POST, instance=request.user,request.FILES or None)

will fixed the error. add (request.FILES or None) on the form instance to accept files that includes img

Related