Обновление аватара профиля 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:

Попробуйте разгруппировать вызов 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)