简体   繁体   English

Django Rest 框架无效的序列化数据,不知道为什么

[英]Django Rest Framework invalid serializer data, can not figure out why

I am creating a simple model with a many-to-many field.我正在创建一个带有多对多字段的简单 model。 The model works fine and I can create model through the admin panel, and I can make a get request to see that model (except that it only returns user IDs instead of the user models/objects). model 工作正常,我可以通过管理面板创建 model,我可以发出获取请求以查看 model(除了它只返回用户模型/对象而不是用户 ID)。 My problem is when creating a post request to create said model.我的问题是在创建发布请求以创建所述 model 时。

I get one of the two errors depending on the changes I make, The serializer field might be named incorrectly and not match any attribute or key on the 'str' instance.根据我所做的更改,我得到了两个错误之一, The serializer field might be named incorrectly and not match any attribute or key on the 'str' instance. or AssertionError: You cannot call '.save()' on a serializer with invalid data.AssertionError: You cannot call '.save()' on a serializer with invalid data. , either way it has something to do with my serializer. ,无论哪种方式,它都与我的序列化程序有关。 The following is my model,下面是我的model,

class Schema(models.Model):
    week = models.PositiveIntegerField(primary_key=True, 
                                       unique=True,
                                       validators=[MinValueValidator(1), MaxValueValidator(53)],
                                       )
    users = models.ManyToManyField(MyUser, related_name="users")

    class Meta:
        ordering = ('week',)

My View,我的观点,

class SchemaView(APIView):
    permission_classes = (SchemaPermissions,)

    def get(self, request):
        schemas = Schema.objects.all()
        serializer = SchemaSerializer(schemas, many=True)

        return Response(serializer.data)

    def post(self, request):
        data = request.data
        serializer = SchemaSerializer(data=data)
        serializer.is_valid()
        serializer.save()
        return Response(serializer.data, status=status.HTTP_200_OK)

And my serializer,还有我的序列化器,

class SchemaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Schema
        fields = ('week', 'users')

    def create(self, validated_data):
        users_data = validated_data.pop('users')
        users = MyUser.objects.filter(id__in=users_data)
        schema = Schema.objects.create(week=validated_data.week, users=users)

        return schema

    def update(self, instance, validated_data):
        users_data = validated_data.pop('users')
        users = MyUser.objects.filter(id__in=users_data)
        instance.users.clear()
        instance.users.add(*users)
        instance.saver()
        return instance

The idea is that if a week number already exists then it should call the update() function and then it should simply overwrite the users related to that week number, otherwise it should call create() and create a new week number with relations to the given users.这个想法是,如果一个周数已经存在,那么它应该调用 update() function 然后它应该简单地覆盖与该周数相关的用户,否则它应该调用 create() 并创建一个与给定用户。 The following is the result of printing the serializer after initializing it in the view.下面是在视图中初始化序列化器后打印的结果。

SchemaSerializer(data={'week': 32, 'users': [1, 2, 3]}):
    week = IntegerField(max_value=53, min_value=1, validators=[<UniqueValidator(queryset=Schema.objects.all())>])
    users = PrimaryKeyRelatedField(allow_empty=False, many=True, queryset=MyUser.objects.all())

It seems to me that the serializer should be valid for the given model?在我看来,序列化程序应该对给定的 model 有效? I am perhaps missing some concepts and knowledge about Django and DRF here, so any help would be greatly appreciated!我可能在这里遗漏了一些关于 Django 和 DRF 的概念和知识,所以任何帮助将不胜感激!

First you need set the field for saving users in the SchemaSerializer .首先,您需要在SchemaSerializer中设置用于保存users的字段。 And you don't need to customize the create and update method because the logic could be coded in the views .而且您不需要自定义createupdate方法,因为逻辑可以在views中编码。

class SchemaSerializer(serializers.ModelSerializer):
    users = UserSerializer(read_only = True, many = True)
    user_ids = serializers.ListField(
        child = serializers.IntegerField,
        write_only = True
    )

    class Meta:
        model = Schema
        fields = ('week', 'users', 'user_ids',)

    # remove create and update method

And in views.py,在views.py中,

class SchemaView(APIView):
    permission_classes = (SchemaPermissions,)

    def get(self, request):
        ...

    def post(self, request):
        data = request.data
        serializer = SchemaSerializer(data=data)
        if serializer.is_valid():
            input_data = serializer.validated_data
            week = input_data.get('week')
            user_ids = input_data.get('user_ids')
            if Schema.objects.filter(week = week).count() > 0:
                schema = Schema.objects.get(week = week).first()
            else:
                schema = Schema.objects.create(week = week)
            schema.users.set(user_ids)
            schema.save()
        
            return Response(SchemaSerializer(schema).data, status=status.HTTP_200_OK)
        else:
            print(serializer.errors)
            return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST)

And of course, the payload data should be当然,有效载荷数据应该是

{'week': 23, 'user_ids': [1,2,3]}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM