Django REST Framework 3中的其他序列化程序字段

nma*_*rko 15 python django django-rest-framework

情况

我正在创建一个允许创建用户的简单端点.我需要一个不在我的用户模型中的字段(即confirm_password).我将运行验证,将此字段与模型中的另一个字段进行比较,然后再从不在序列化程序中再使用其他字段.

问题

DRF版本3已经改变了完成此任务的过程,我不太明白文档建议我做什么.请参阅此处获取文档.

尝试解决方案

我创建了一个UserSerializer如下所示:

from django.contrib.auth import get_user_model
from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    confirm_password = serializers.CharField(allow_blank=False)

    def validate(self, data):
        """
        Checks to be sure that the received password and confirm_password
        fields are exactly the same
        """
        if data['password'] != data.pop('confirm_password'):
            raise serializers.ValidationError("Passwords do not match")
        return data

    def create(self, validated_data):
        """
        Creates the user if validation succeeds
        """
        password = validated_data.pop('password', None)
        user = self.Meta.model(**validated_data)
        user.set_password(password)
        user.save()
        return user

    class Meta:
        # returns the proper auth model
        model = get_user_model()
        # fields that will be deserialized
        fields = ['password', 'confirm_password',
                  'username', 'first_name', 'last_name', 'email']
        # fields that will be serialized only
        read_only_fields = ['is_staff', 'is_superuser']
        # fields that will be deserialized only
        write_only_fields = ['password' 'confirm_password']
Run Code Online (Sandbox Code Playgroud)

我希望,啪confirm_passwordvalidate会照顾我关心的问题,但我只是得到如下结果:

KeyError试图获得值场时,confirm_password在串行UserSerializer.序列化程序字段可能名称不正确,并且与OrderedDict实例上的任何属性或键都不匹配

Kev*_*own 27

您正在寻找一个只写字段,因为我假设您不希望在API中显示密码确认.Django REST Framework write_only在2.3.x时间轴中引入了参数以补充read_only参数,因此运行验证的唯一时间是进行更新时.该write_only_fields元财产大约在同一时间加入,而是要了解这两个一起工作是很重要的.

write_only_fields元属性将自动添加的write_only属性字段时会自动创建它,像一个password在现场User的模型.它不会对已在串行已明确指定哪些不是在模型中的任何字段,或者域做到这一点.在您的情况下,您明确指定confirm_password序列化程序中的字段,这就是它不起作用的原因.

KeyError试图获得值场时,confirm_password在串行UserSerializer.序列化程序字段可能名称不正确,并且与OrderedDict实例上的任何属性或键都不匹配

这是在创建用户重新序列化时尝试序列化confirm_password字段时引发的.因为它无法在User模型上找到该字段,所以它会触发此错误,该错误会尝试解释该问题.不幸的是,因为这是一个用户,它告诉你混淆地查看OrderedDict实例而不是User实例.

class UserSerializer(serializers.ModelSerializer):
    confirm_password = serializers.CharField(allow_blank=False, write_only=True)
Run Code Online (Sandbox Code Playgroud)

如果您write_only在序列化程序字段中明确指定,并从您的字段中删除该字段write_only_fields,那么您应该看到您期望的行为.

您可以在此链接上找到有关此文档的文档