Django Rest Framework,更新嵌套的序列化数据

时间:2017-06-29 16:24:58

标签: python django serialization django-rest-framework

我是使用Django Rest Framework和序列化数据的新手,我正在尝试更新嵌套的序列化程序,但遇到了墙,我环顾四周但是大多数人在serializers.py方面遇到问题而我甚至无法在没有错误的情况下进入def更新,这些是我的类:

Views.py

from django.shortcuts import render
from rest_framework import generics
from api.serializers import ProfileSerializer
from django.contrib.auth.models import User
from api.models import Profile
from django.http import JsonResponse

class ProfileView(generics.ListCreateAPIView):
    def get(self, request):
        profile = Profile.objects.filter(user_id=request.user.id)
        serializer = ProfileSerializer(profile, many=True)
        return JsonResponse(serializer.data, safe=False)
    def post(self, request, *args, **kwargs):
        profile = Profile.objects.filter(user_id=request.user.id)
        data = request.POST
        serializer = ProfileSerializer(profile, data=data, partial=True)
        if serializer.is_valid():
            serializer.save()
        else:
            print(serializer.errors)
        return JsonResponse(serializer.data, safe=False)

Serializers.py

from rest_framework import serializers
from django.contrib.auth.models import User
from api.models import Profile

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id','username','first_name','last_name','email','last_login','date_joined','is_active')

class ProfileSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    class Meta:
        model = Profile
        fields = ('id','phone','birth_date','user')

        def update(self, instance, validated_data):
            #Cant get here
            print("hey")
            return instance

示例结构

[
    {
        "id": 3,
        "phone": "XXXXXX",
        "birth_date": "2017-06-29",
        "user": {
            "id": 1,
            "username": "xxxxx",
            "first_name": "XXXXX",
            "last_name": "XXXX",
            "email": "xxxxxxx@gmail.com",
            "last_login": "2017-06-29T15:16:11.438818Z",
            "date_joined": "2017-06-23T16:48:38Z",
            "is_active": true
        }
    }
]

我当前的错误: (发布数据:电话= 0000000)

AttributeError at /profile/
'QuerySet' object has no attribute '_meta'

谢谢!

3 个答案:

答案 0 :(得分:4)

您会看到此错误,因为您将queryset而非实例传递给序列化程序__init__。要解决错误更改:

def post(self, request, *args, **kwargs):
    profile = Profile.objects.filter(user_id=request.user.id)

到此:

def post(self, request, *args, **kwargs):
    profile = Profile.objects.get(user_id=request.user.id)

换句话说,而不是filter返回的queryset,您需要get返回的Profile实例。

<强> UPD

更新嵌套用户尝试这个(没有测试它,让我知道这是否有任何错误):

def update(self, instance, validated_data):
    user = validated_data.get('user')
    instance.user.first_name = user.get('first_name')
    instance.user.save()

    print("hey")
    return instance

答案 1 :(得分:4)

发现自己处于类似情况,我能够解决如下问题。希望它有所帮助。

def update(self, instance, validated_data):
    user_data = validated_data.pop('user')
    user_serializer = UserSerializer()
    super(self.__class__, self).update(instance,validated_data)
    super(UserSerializer,user_serializer).update(instance.user,user_data)
    return instance

答案 2 :(得分:0)

我遇到了类似的问题,并使用解决方法解决了它。首先让我解释一下我的情况。当在JS页面上按下SUBMIT按钮时,它将触发REST API,该API将使现有数据库项目的计数增加1。因此,我将传入的JSON请求的内容解析为一个变量,例如A。变量是不可变的,所以我创建了一个新变量X,然后以一种可以将其发送到可序列化类的格式添加了值: X = {'item_name': A["item_name"], 'count_of_votes': last_count + 1} 然后 serializer_class_Object = serializer_class(existing_object_ref, data=X)