在用于创建模型的序列化器中,我想将我的模型字段重命名为(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',)
Serializer
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。
我尝试过的
删除串行器中source
和PrimaryKeyRelatedField
的user_id
上的question_id
字段实际上导致绕过DRF中的unique_together验证,并避免了KeyError。但是,已验证的数据不会映射回原始字段名称(user
和question
)。在这种情况下,我们必须先手动将密钥更改回其原始名称,然后才能从已验证的数据创建Model的实例。
有更好的方法吗?
您可以制作自定义序列化器,如:-
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