我正在尝试使用DRF和Ajax保存用户个人资料数据,但是出现KeyError错误。
我正在阅读DRF文档,特别是这部分:Writable Nested Representations那是我想要的,但是对我不起作用。
希望你能帮助我
这是我的 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)
和我的 ajax.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()
和其他模型。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:\Users\a_niu\.virtualenvs\Vinculacion-S2cHiiVR\lib\site-packages\rest_framework\generics.py", line 288, in patch
return self.partial_update(request, *args, **kwargs)
File "C:\Users\a_niu\.virtualenvs\Vinculacion-S2cHiiVR\lib\site-packages\rest_framework\mixins.py", line 82, in partial_update
return self.update(request, *args, **kwargs)
File "C:\Users\a_niu\.virtualenvs\Vinculacion-S2cHiiVR\lib\site-packages\rest_framework\mixins.py", line 68, in update
self.perform_update(serializer)
File "C:\Users\a_niu\.virtualenvs\Vinculacion-S2cHiiVR\lib\site-packages\rest_framework\mixins.py", line 78, in perform_update
serializer.save()
File "C:\Users\a_niu\.virtualenvs\Vinculacion-S2cHiiVR\lib\site-packages\rest_framework\serializers.py", line 208, in save
self.instance = self.update(self.instance, validated_data)
File "C:\Users\a_niu\Desktop\practicas\Django\Vinculacion\app\profiles\serializers.py", line 24, in update
profile_data = validated_data.pop('profile')
KeyError: 'profile'
答案 0 :(得分:0)
再看看您给的example:
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
字段。我认为您正在将其与profile
类的UserSerializer
属性混为一谈,这与{的嵌套profile
对象不同{1}}模型。