Django - KeyError: 'profile' - 尝试使用 DRF 和 Ajax 保存用户配置文件



我正在尝试使用 DRF 和 Ajax 保存用户配置文件数据,但我有一个错误 KeyError。

我正在阅读DRF文档,特别是这一部分:可写嵌套表示,这是我想要的,但对我不起作用。

希望你能帮助我

这是我的 serializer.py

class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ('user', 'avatar', 'dob', 'headline',
'country', 'location', 'cp', 'background',
'facebook', 'twitter', 'github', 'website',)
read_only_fields = ('user', ) # I tried removing this part but, not work (In some forums say it)

class UserSerializer(serializers.ModelSerializer):
profile = ProfileSerializer()
class Meta:
model = User
exclude = ('password', 'is_superuser', 'is_staff', 'is_active', 'user_permissions', 'groups', 'last_login',)
read_only_fields = ('username', 'email', 'date_joined', )
def update(self, instance, validated_data):
profile_data = validated_data.pop('profile')
profile = instance.profile
instance.username = validated_data.get('username', instance.username)
instance.first_name = validated_data.get('first_name', instance.first_name)
instance.last_name = validated_data.get('last_name', instance.last_name)
instance.save()
profile.avatar = profile_data.get('avatar', profile.avatar)
profile.dob = profile_data.get('dob', profile.dob)
profile.headline = profile_data.get('headline', profile.headline)
profile.country = profile_data.get('country', profile.country)
profile.location = profile_data.get('location', profile.location)
profile.cp = profile_data.get('cp', profile.cp)
profile.background = profile_data.get('background', profile.background)
profile.facebook = profile_data.get('facebook', profile.facebook)
profile.twitter = profile_data.get('twitter', profile.twitter)
profile.github = profile_data.get('github', profile.github)
profile.website = profile_data.get('website', profile.website)
profile.save()
return instance

我的views.py

class ProfileRetrieveAPIView(generics.RetrieveUpdateDestroyAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsAuthenticatedOrReadOnly, IsAuthenticatedOrReadOnly, )
lookup_field = 'username'
def retrieve(self, request, *args, **kwargs):
super(ProfileRetrieveAPIView, self).retrieve(request, args, kwargs)
instance = self.get_object()
serializer = self.get_serializer(instance)
data = serializer.data
response = {
"message": "Successfully retrieved",
"data": data,
"status_code": status.HTTP_200_OK
}
return Response(response)
def patch(self, request, *args, **kwargs):
super(ProfileRetrieveAPIView, self).patch(request, args, kwargs)
instance = self.get_object()
serializer = self.get_serializer(instance)
data = serializer.data
response = {
"message": "Perfil actualizado con éxito",
"data": data,
"status": status.HTTP_200_OK
}
return Response(response, status=status.HTTP_200_OK)

还有我的阿贾克斯.js

$("#saveProfile").click(function(e) {
e.preventDefault();
var profileData = {
'avatar': $("#avatar").val(),
'first_name': $("#first_name").val(),
'last_name': $("#last_name").val(),
'country': $("#country").val(),
'location': $("#location").val(),
'cp': $("#postal_code").val(),
'headline': $("#headline").val(),
'dob': $("#dob").val(),
'facebook': $("#facebook").val(),
'twitter': $("#twitter").val(),
'github': $("#github").val(),
'website': $("#website").val(),
}
$.ajax({
type: 'PATCH',
url: "{% url 'profiles:api_profile' username=request.user.username %}",
data: JSON.stringify(profileData),
contentType: 'application/json; charset=utf-8',
success: function(res) {
console.log(res.data);
},
error: function(res) {
console.log(res);
}
});
});

更新,我添加了 models.py**

class Profile(TimeStampedModel):
user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name="profile", on_delete=models.CASCADE)
avatar = ThumbnailerImageField(upload_to=user_directory_path, blank=True, validators=[validate_image_extension])
dob = models.DateField(_("Date of Birth"), blank=True, null=True)
headline = models.CharField(_("Headline"), max_length=255)
country = models.CharField(_("Country"), max_length=100, blank=True)
location = models.CharField(_("Location"), max_length=255, blank=True)
cp = models.CharField(_("Postal Code"), max_length=5, blank=True)
#sector = models.TextField(_("Sector"))
background = ThumbnailerImageField(upload_to='photos/', blank=True, validators=[validate_image_extension])
#contact information
facebook = models.URLField(_("Facebook"), max_length=200, blank=True, null=True)
twitter = models.URLField(_("Twitter"), max_length=200, blank=True, null=True)
github = models.URLField(_("GitHub"), max_length=200, blank=True, null=True)
website = models.URLField(_("Website"), max_length=200, blank=True, null=True)
enterprise = models.BooleanField(_("Is enterprise account?"), default=False)

def __str__(self):
return self.user.get_full_name()

和其他 models.py

class TimeStampedModel(models.Model):
"""
Un modelo base abstracto que provee de campos predeterminados
para que no sean repetitivos, se puede heredar de este modelo
a todos los demás para excluir la repeticion de los campos
``created_at`` and ``updated_at``.
"""
created_at = models.DateTimeField(_("Created Date"), auto_now_add=True)
updated_at = models.DateTimeField(_("Updated Date"), auto_now=True)
class Meta:
abstract = True
class User(AbstractUser):
role = models.BooleanField(_("Enterprise Account"), default=False)

当我按下保存按钮时,服务器给我这个错误:

File "C:Usersa_niu.virtualenvsVinculacion-S2cHiiVRlibsite-packagesrest_frameworkgenerics.py", line 288, in patch
return self.partial_update(request, *args, **kwargs)
File "C:Usersa_niu.virtualenvsVinculacion-S2cHiiVRlibsite-packagesrest_frameworkmixins.py", line 82, in partial_update
return self.update(request, *args, **kwargs)
File "C:Usersa_niu.virtualenvsVinculacion-S2cHiiVRlibsite-packagesrest_frameworkmixins.py", line 68, in update
self.perform_update(serializer)
File "C:Usersa_niu.virtualenvsVinculacion-S2cHiiVRlibsite-packagesrest_frameworkmixins.py", line 78, in perform_update
serializer.save()
File "C:Usersa_niu.virtualenvsVinculacion-S2cHiiVRlibsite-packagesrest_frameworkserializers.py", line 208, in save
self.instance = self.update(self.instance, validated_data)
File "C:Usersa_niuDesktoppracticasDjangoVinculacionappprofilesserializers.py", line 24, in update
profile_data = validated_data.pop('profile')
KeyError: 'profile'

再看看你给出的例子:

class UserSerializer(serializers.ModelSerializer):
profile = ProfileSerializer()
class Meta:
model = User
fields = ['username', 'email', 'profile']
def create(self, validated_data):
profile_data = validated_data.pop('profile')
user = User.objects.create(**validated_data)
Profile.objects.create(user=user, **profile_data)
return user

这与你的代码不同,因为profile作为字段包含在meta.fields中,而看起来你没有在代码中包含profile字段。 我认为您将其与UserSerializer类的profile属性混淆了,该属性User模型的嵌套profile对象不同。

最新更新