【问题标题】:Django DRF rename field in serializer but unique_together validation fails序列化程序中的 Django DRF 重命名字段,但 unique_together 验证失败
【发布时间】:2020-05-27 12:19:34
【问题描述】:

在用于创建模型的序列化程序中,我想将模型字段重命名为 (field_name)_id,以便 API 使用者更清楚该字段是 ID 字段。该模型还对某些字段具有unique_together 约束。但是,当验证在序列化程序中运行时,它会失败并显示字段不存在的 KeyError:

...rest_framework/utils/serializer_helpers.py", line 148, in __getitem__
    return self.fields[key]
KeyError: 'question'

有没有一种简单的方法可以让它工作?下面是最小的示例代码。

型号

class MyModel(Model):
            question = ForeignKey('uppley.Question', null=False, on_delete=PROTECT)
            user = ForeignKey('catalystlab.User', null=False, on_delete=PROTECT)

            class Meta:
                unique_together = ('question', 'user',)

序列化器

        class MyCreateSerializer(ModelSerializer):

            question_id = PrimaryKeyRelatedField(
                write_only=True,
                source='question',
                queryset=Question.objects.all(),
            )

            user_id = PrimaryKeyRelatedField(
                write_only=True,
                source='user',
                queryset=User.objects.all(),
            )

            class Meta:
                model = MyModel
                fields = ('question_id', 'user_id',)

test.py - 用于演示目的的测试

        question = QuestionFactory()
        user = UserFactory()

        data = {
            'question_id': question.id,
            'user_id': user.id,
        }
        serializer = MyCreateSerializer(data=data, write_only=True)
        is_valid = serializer.is_valid(raise_exception=True) #KeyError exception raised here.

以前在 DRF 3.10.3 中一切正常,但在 3.11.0 中,现在如上所述抛出 KeyError。

我的尝试

删除序列化器中PrimaryKeyRelatedField 上的user_idquestion_idsource 字段实际上会导致绕过DRF 中的unique_together 验证,并且避免了KeyError。但是,经过验证的数据不会映射回原始字段名称(userquestion)。在这种情况下,我们必须手动将键更改回其原始名称,然后才能从验证数据创建模型实例。

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    您可以制作自定义序列化程序,例如:-

    class MyCreateSerializer(serializers.Serializer):
    
        question_id = serializers.PrimaryKeyRelatedField(
             write_only=True,
             queryset=Question.objects.all(),
        )
    
        user_id = PrimaryKeyRelatedField(
             write_only=True,
             queryset=User.objects.all(),
        )
    

    并在其中创建自定义创建函数以创建对象。喜欢:-

    def create(self, validated_data):
        try:
            question = validated_data.get('question_id')
            user = validated_data.get('user_id')
            instance = MyModel.objects.create(question=question, user=user)
        except TypeError:
            raise TypeError("Something went wrong while creating objects")
    
        return instance
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-20
      • 2020-08-14
      • 2019-02-19
      • 2014-05-02
      • 2020-04-16
      • 2017-11-09
      • 2017-01-12
      相关资源
      最近更新 更多