Обновление аватара профиля DRF и Vue.js

Я не совсем понимаю, почему я не могу обновить url изображения в моем DRF api. Я использую djoser для конечных точек api и активации, django rest framework и vue.js для фронтенда с axios, делающим запросы API. Я считаю (и я могу ошибаться!), что я не могу делать патч-запросы с Axios, используя FormData(), поэтому из гугления я нашел другой метод, но я все еще получаю ошибку HTTP 500 и ошибку Django:

Internal Server Error: /api/v1/users/me/
Traceback (most recent call last):
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/rest_framework/viewsets.py", line 125, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/djoser/views.py", line 175, in me
    return self.partial_update(request, *args, **kwargs)
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/rest_framework/mixins.py", line 82, in partial_update
    return self.update(request, *args, **kwargs)
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/rest_framework/mixins.py", line 68, in update
    self.perform_update(serializer)
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/djoser/views.py", line 149, in perform_update
    super().perform_update(serializer)
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/rest_framework/mixins.py", line 78, in perform_update
    serializer.save()
  File "/Users/markmckeon/Django_Stuff/Relate/environment_3_8_8/lib/python3.8/site-packages/rest_framework/serializers.py", line 208, in save
    assert self.instance is not None, (
AssertionError: `update()` did not return an object instance.

Я не уверен в том, является ли это проблемой бэкенда с тем, как обрабатывается файл изображения, или это то, как фронтенд отправляет файл?

Вот мой serializers.py:

class UserSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer(required=False, allow_null=True)
    
    class Meta:
        model = User
        fields = ['username', 'profile', 'password']
        extra_kwargs = {"password":{'write_only': True}}

    

    def update(self, instance, validated_data):
        parser_classes = (MultiPartParser)
        if 'profile' in validated_data:
            nested_serializer = self.fields['profile']
            nested_instance = instance.profile
            nested_data = validated_data.pop('profile')

            nested_serializer.update(nested_instance, nested_data)


            return super(UserSerializer, self).update(instance, validated_data) 

    def create(self, validated_data):
        return User.objects.create_user(**validated_data)

Как вы видите, я обновляю вложенную модель User, чтобы сохранить профиль пользователя и его данные вместе.

Vue.js:

methods: {

     updateAvatar() {

          const token = localStorage.getItem('token')
          const image = this.fileName
          const formData = new FormData();
                    const data = {
                    profile: {
                        avatar: image,
                        },
                    username: this.user_profile[0]["username"],
                    password: token
                  };
          console.log("Pre send: ", data);

          for(let dataKey in data) {
            if(dataKey === 'avatar') {
              // append nested object
              for (let previewKey in data[dataKey]) {
                formData.append(`avatar[${previewKey}]`, data[dataKey][previewKey]);
              }
            }
            else {
              formData.append(dataKey, data[dataKey]);
            }
          }

          const base = {
                    baseURL: 'http://127.0.0.1:8000',
                    headers: {
                            "Content-Type": "multipart/form-data"
                    },
                    xhrFields: {
                      withCredentials: true
                    }
                  };
          const axiosInstance = axios.create(base);
                      axiosInstance({
                        url: "/api/v1/users/me/",
                        data: formData,
                        method: "patch"
                      })
          // axios

          //   .patch(`/api/v1/users/me/`, formData)
            
            .then((response) => {
              const newArray = response.data;
              console.log("Userchanges: ", newArray);
            })

            .catch((error) => console.log(error.response));
    }
  },

И, наконец, мой экземпляр пользователя DRF: DRF User profile

Попробуйте разгруппировать вызов super в вашем методе update:

def update(self, instance, validated_data):
    parser_classes = (MultiPartParser)
    if 'profile' in validated_data:
        ...

    # unindented
    return super(UserSerializer, self).update(instance, validated_data)
Вернуться на верх