【问题标题】:Django rest framework serializer.save() return "Invalid data. Expected a dictionary, but got group"Django rest 框架 serializer.save() 返回“无效数据。需要字典,但有组”
【发布时间】:2018-04-18 15:24:16
【问题描述】:

我正在尝试调用 serlizerer 从视图集中保存对象 这是views.py

class GroupViewSet(viewsets.ViewSet):
        ....
        @detail_route(methods=['post'], url_path='task')
        def get_task(self, request, pk=None):
            group = get_object_or_404(Group, pk=pk)
            data = {"group": group }
            log_serializer = LogSerializer(data=data)
            if log_serializer.is_valid(raise_exception=True):
                log_serializer.save()

这是serializer.py

class GroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = Group
        fields = ('id', 'name')

class LogSerializer(serializers.ModelSerializer):
    group = GroupSerializer()
    class Meta:
        model = Log
        fields = ('group', 'created')

这是model.py:

class Group:
....

class Log(models.Model):
    user = models.ForeignKey(User)
    group = models.ForeignKey(Server) #Not the group of user , it is the group id which user try to query 
    created = models.DateTimeField(auto_now_add=True)

回复;

{
    "group": {
        "non_field_errors": [
            "Invalid data. Expected a dictionary, but got group."
        ]
    }
}

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    根据您的 LogSerializer,当您将 data 属性传递给序列化器时,它需要这样的字典:

    {
        // note this is a dictionary or a JSON Object.
        // id is omitted because it's auto-inserted natural key
        {
            'name': 'group-name'
        },
        'created': '2017-11-06 20:17:59'
    }
    

    但是,您传递了一个组实例,您可以从这里获得:group = get_object_or_404(Group, pk=pk) 所以当您调用 .is_valid 时会引发异常。

    假设您尝试使用 Group 外键创建 Log 对象,对于现有 Group,快速破解方法是将 data = {"group": group } 替换为 data = {"group": group.__dict__ }

    【讨论】:

    • 谢谢,但是 group.__dict__ 会将非只读字段(id 不会被传递)传递给 valid_data,所以我不知道哪个组在传递
    • 是的,它会,但 GroupSerializer 只会验证您指定的字段。而且您仍然可以从这条线上获得您的小组:group = get_object_or_404(Group, pk=pk)。因此,如果您需要对组对象做一些事情,您也可以这样做。我想,让我问一下你到底想在这里完成什么,因为如果你想创建一个嵌套对象,有更好的方法来做到这一点。
    • 感谢您的帮助,我不确定它是否是嵌套对象。这是我想要完成的地方,def get_task 是获取组任务的端点(例如 /group/8/task 将获得第 8 组的任务),我想注销查询这个的用户和她尝试的组查询。
    • 目前,我采用stackoverflow.com/questions/29950956/…提供的方法
    • 但是如果我可以直接传递obj而不是提取id然后传递就好了
    猜你喜欢
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-09
    • 2017-08-21
    相关资源
    最近更新 更多