2016-03-23 2 views
1

Я пытаюсь заменить один проверенный объект другим, используя запрос PATCH. Для моих экспериментов я использую Postman. Я отправить запрос PATCH с параметром user_status и значением:Django REST - PATCH для замены вложенного объекта

{ "ID": 1, "status_type": { "ID": 2, "название": "new_status_type_name"}, "название" : «new_status_name "}

Я написал метод обновления для обновления моего ResultSerializer, но он не работает. Теперь я отлаживаю его, и я вижу, что переменная validated_data не содержит мой новый user_status. user_status пустая OrderedDict:

ipdb> validated_data['user_status'] 
OrderedDict() 

Я проверил мою просьбу, и я вижу, что user_status список с одним элементом - строка.

ipdb> self.context['request'].data 
<QueryDict: {'user_status': ['{"id": 1, "status_type": {"id": 2, "name": "new_status_type_name"}, "name": "new_status_name"}']}> 

Как заменить другие вложенные объекты? Спасибо за помощь.

У меня есть следующие модели:

class UserStatus(models.Model): 
    id = models.AutoField(primary_key=True) 
    name = models.CharField(unique=True, max_length=255) 
    status_type = models.ForeignKey('StatusType', blank=True, null=True) 

    class Meta: 
     managed = False 
     db_table = 'user_status' 

    def __str__(self): 
     return self.name 


class StatusType(models.Model): 
    id = models.SmallIntegerField(primary_key=True) 
    name = models.CharField(unique=True, max_length=256) 

    class Meta: 
     managed = False 
     db_table = 'status_type' 

    def __unicode__(self): 
     return self.name 

class Result(models.Model): 
    id = models.BigIntegerField(primary_key=True) 
    user_status = models.ForeignKey('UserStatus', blank=True, null=True) 

    class Meta: 
     managed = False 
     db_table = 'result' 

сериализаторы:

class UserStatusSerializer(serializers.ModelSerializer): 
    id = serializers.IntegerField() 
    name = serializers.CharField() 
    status_type = StatusTypeSerializer() 

    class Meta: 
     model = app.models.UserStatus 


class StatusTypeSerializer(serializers.ModelSerializer): 
    id = serializers.IntegerField() 
    name = serializers.CharField() 

    class Meta: 
     model = app.models.StatusType 


class ResultSerializer(serializers.ModelSerializer): 
    user_status = UserStatusSerializer(many=False) 

    def update(self, instance, validated_data, *args, **kwargs): 
     import ipdb; ipdb.set_trace() 
     instance.user_status = validated_data.get('user_status', instance.user_status) 
     instance.save() 
     return instance 

    class Meta: 
     model = app.models.Result 

Просмотров:

class StatusTypeViewSet(viewsets.ModelViewSet): 
    queryset = app.models.StatusType.objects.all() 
    serializer_class = app.serializers.StatusTypeSerializer 


class UserStatusViewSet(viewsets.ModelViewSet): 
    queryset = app.models.UserStatus.objects.all() 
    serializer_class = app.serializers.UserStatusSerializer 


class ResultViewSet(viewsets.ModelViewSet): 
    queryset = app.models.Result.objects.all() 
    serializer_class = app.serializers.ResultSerializer 

ответ

0

После прочтения этой статьи Please. Don't Patch Like An Idiot. я понял, что я должен использовать список исправления, но Django REST не хочет использовать список, только объекты , Хорошо, теперь я использую следующий Dict для pathcing:

{"op": "update", "field": "user_status_id", "new_value": 2} 

и следующий код для отправки этого списка:

import json 
import requests 

payload = json.dumps({"op": "update", "field": "user_status_id", "new_value": 2}) 
headers = {'content-type': "application/json"} 
response = requests.patch(url, data=payload, headers=headers) 

Тогда я изменил serializers.py и views.py. Я покажу вам только основной код без проверки и других stufs :). views.py (добавлен метод perform_update):

class ResultViewSet(viewsets.ModelViewSet): 
    queryset = app.models.Result.objects.all() 
    serializer_class = app.serializers.ResultSerializer 

    def perform_update(self, serializer): 
     new_value = self.request.data.get('new_value') 
     user_status_ins = app.models.UserStatus.objects.get(id=new_value) 
     serializer.save(user_status=user_status_ins) 

serializers.py (добавлен метод update):

class ResultSerializer(serializers.ModelSerializer): 
    user_status = UserStatusSerializer(many=False) 

    def update(self, instance, validated_data, *args, **kwargs): 
     for field in validated_data.keys(): 
      setattr(instance, field, validated_data.get(field)) 
     instance.save() 
     return instance 

    class Meta: 
     model = app.models.Result 

Если вы нашли лучшее решение, пожалуйста, скажите мне.

Смежные вопросы