Как я могу обновить данные вложенного сериализатора в django rest framework?
Привет, я новичок в django rest framework, я хочу выполнить операцию обновления на вложенных сериализованных данных, но не могу выполнить ее. Кто-нибудь, пожалуйста, посмотрите на это и предложите мне, чтобы это можно было решить. Спасибо
My Models are:
class MyUser(AbstractUser):
bio = models.CharField(max_length=500, blank=True)
is_younger = models.BooleanField(default=False)
friends = models.ManyToManyField('self',blank=True, related_name="friends")
class Profile(models.Model):
genders = [
("M", "Male"),
("F", "Female"),
]
user = models.ForeignKey(MyUser, on_delete=models.CASCADE)
age = models.IntegerField(null=True)
gender = models.CharField(max_length=1, choices=genders)
contact = PhoneField(blank=True, help_text='Contact phone number')
address = models.CharField(max_length=100, blank=True)
profilepic = models.ImageField(upload_to="profile/", db_index=True, default="profile/default.jpg")
def __str__(self):
return self.user.username
----Serializers are:
class UsersProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = '__all__'
class ListUsersSerializer(serializers.ModelSerializer):
profile = UsersProfileSerializer(
read_only=True, many=True, source='profile_set')
class Meta:
model = MyUser
fields = ['id', 'username', 'email', 'is_younger',
'friends', 'profile']
def update(self, instance, validated_data):
profiles_data = validated_data.pop('profile')
profiles = (instance.profile).all()
profiles = list(profiles)
instance.bio = validated_data.get('bio', instance.bio)
instance.save()
for profile_data in profiles_data:
profile = profiles.pop(0)
profile.contact = profile_data.get('contact', profile.contact)
profile.address = profile_data.get('address', profile.address)
profile.save()
return instance
Below is View code:
class CheckUserDetailsViewSet(viewsets.ViewSet):
permission_classes = [AllowAny]
queryset = MyUser.objects.all()
def list(self, request):
serializer = ListUsersSerializer(self.queryset,many=True)
return Response(serializer.data)
def retrieve(self, request,pk=None):
user = generics.get_object_or_404(self.queryset,pk=pk)
serializer = ListUsersSerializer(user)
return Response(serializer.data)
Я знаю, я должен создать метод обновления в коде набора представлений, но я нашел несколько связанных кодов и использовал их, сделав некоторые изменения в соответствии с моими потребностями, но они не работают. Если есть проблема в методе обновления моего сериализатора, то, пожалуйста, укажите на мою ошибку или это можно сделать, написав метод обновления в представлениях, тогда, пожалуйста, дайте мне подсказку или предоставьте мне код. Спасибо
Представляю, что существует множество способов решения этой проблемы, и вот один из них. Иметь представление, которое переключается между двумя сериализаторами в зависимости от запроса, и переопределить метод update в сериализаторе update. Таким образом, вы будете обновлять пользователя через конечную точку профиля, используя ключ user_data.
Имеют сериализаторы PATCH/PUT
class UsersProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = '__all__'
class UsersProfileUpdateSerializer(serializers.ModelSerializer):
user_data = serializers.DictField()
class Meta:
model = Profile
fields = '__all__'
def update(self, instance, validated_data):
user_data = validated_data.pop('user_data', None)
for (key, value) in validated_data.items():
setattr(instance, key, value)
if user_data is not None:
user_instance = instance.user
for (key, value) in user_data.items():
setattr(user_instance, key, value)
user_instance.save()
instance.save()
return instance
Вид:
class UserProfileViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = Profile.objects.all()
def get_serializer_class(self):
if self.action == 'update':
return UsersProfileUpdateSerializer
return UsersProfileSerializer
Пример объекта обновления:
{
"age":18,
"user_data": {
"bio": "update"
}
}