【问题标题】:Django Rest Framework, updating nested serialized dataDjango Rest Framework,更新嵌套的序列化数据
【发布时间】:2017-12-03 11:18:47
【问题描述】:

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

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'

谢谢!

【问题讨论】:

    标签: python django serialization django-rest-framework


    【解决方案1】:

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

    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
    

    【讨论】:

    • 您正在实例化一个没有对象或“数据”关键字参数的 UserSerializer。我相信这是因为 user_data 不完全适合传递给 UserSerializer。但这仍然是使用 Serializer 的错误方式,不是吗?
    【解决方案2】:

    您看到此错误是因为您将查询集而不是实例传递给序列化程序 __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)
    

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

    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
    

    【讨论】:

    • 太棒了!这适用于正常更新,我可以更改上层(电话)上的数据,但你能帮我更新嵌套集的数据吗? (例如更改用户名)我尝试发布user.email = something 但收到以下错误The .update() method does not support writable nested fields by default. 我该如何编写自定义更新方法来做到这一点?再次感谢
    • 我仍然得到同样的错误,看起来它会工作,但我似乎根本没有进入那个功能,当我发布数据时它会尝试默认更新而不是我的自定义一,我是否需要在我的视图中使用 .update() 或其他东西来指定它?
    • @Amirgem 哦,我明白了,从 Meta 类中删除更新。这应该直接在 Serializer 类中,与 Meta 相同。
    • 我正要打错了哈哈,谢谢!
    • 我想在更新时将数据显示到字段中你知道我们如何在嵌套序列化中做到这一点......因为否则我会得到空或空白字段,所以如果我编辑一个字段,它会向我显示一个错误,这些字段不能为空白或空......请帮助......谢谢
    【解决方案3】:

    我遇到了类似的问题,并使用解决方法解决了它。首先让我解释一下我的场景。当在 JS 页面上按下 SUBMIT 按钮时,它将触发一个 REST API,它将现有 DB 项的计数增加 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)

    【讨论】:

      猜你喜欢
      • 2016-02-09
      • 2018-06-04
      • 2017-01-28
      • 1970-01-01
      • 1970-01-01
      • 2018-10-26
      • 2023-03-26
      • 2018-02-17
      • 1970-01-01
      相关资源
      最近更新 更多