Обновлять / объединять данные вместо замены их методом PUT в Django Rest Framework

#django #django-rest-framework #put

#django #django-rest-framework #поместить

Вопрос:

В приложении Django (использующем DRF) у меня есть модель профиля пользователя. Чтобы обновить информацию о профиле, я хочу использовать PUT. Однако у меня есть поле с именем «meta», которое само является объектом / dict. Если мне не хватает какого-либо из его свойств (пол, мобильный, день рождения), я потеряю эти данные, поскольку вся «мета» заменяется новой. Этого не происходит ни с одним из полей (например, если я не укажу первое имя, поле останется прежним). Вот пример тела запроса PUT:

 {
    "id": 1,
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "jane@example.com",
    "meta": {
        "gender": "female",
        "mobile": 123456789,
        "birthday":"01-01-1970"
    }
}
  

Что я могу сделать, чтобы гарантировать, что недостающие свойства не будут потеряны? Есть ли способ реализовать или принудительно объединить / обновить предыдущие данные с данными в запросе?

Вот метод:

     def put(self, request, pk):
        user = User.objects.get(id=pk)
        serializer = UserSerializer(user, data=request.data, context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
  

И вот сериализатор:

 class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = [
            'id',
            'url',
            'first_name',
            'last_name',
            'email',
            'meta'
        ]
  

Комментарии:

1. можете ли вы добавить UserSerializer ?>

Ответ №1:

Переопределить update(...) метод сериализатора

 class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = [
            'id',
            'url',
            'first_name',
            'last_name',
            'email',
            'meta'
        ]

    def update(self, instance, validated_data):
        instance_meta = instance.meta.copy()
        instance_meta.update(validated_data.get("meta", {}))
        validated_data["meta"] = instance_meta
        return super().update(instance, validated_data)  

Комментарии:

1. Я пытался сделать что-то подобное. Ваше решение сработало как шарм! Большое вам спасибо!!