Django REST框架中的其他序列化程序字段3 [英] Additional Serializer Fields in Django REST Framework 3

查看:160
本文介绍了Django REST框架中的其他序列化程序字段3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况



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



strong>



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):

检查确认收到的密码和confirm_password
字段是完全一样的

如果data ['password']!= data .pop('confirm_password'):
raise serializers.ValidationError(密码不匹配)
返回数据

def create(self,validated_data):
$
如果验证成功,则创建用户

password = validated_data.pop('password',无)
user = self.Meta.model(** validated_data)
user.set_password(password)
user.save()
return user

class Meta:
#返回适当的验证模型
model = get_user_model()
将反序列化的字段
fields = ['password','confirm_password',
'username','first_name','last_name','email ']
#将仅序列化的字段
read_only_fields = ['is_staff','is_superuser']
#将只反序列化
write_only_fields = ['password'' confirm_password']

我希望弹出 confirm_password validate 将照顾我的问题,但我只是得到以下内容:


得到 KeyError 当尝试在序列化器 UserSe上获取字段 confirm_password 的值rializer 。序列化程序字段可能命名不正确,不符合 OrderedDict 实例



解决方案

你正在寻找一个只写字段,因为我假设你不想在API中显示密码确认。 Django REST框架在2.3.x时间轴中引入了 write_only 参数,以补充 read_only 参数,因此唯一的时间验证运行是在进行更新时。 write_only_fields 元属性大约在同一时间被添加,但是了解这两者之间是如何协同工作的。



write_only_fields 元属性会在自动创建时自动将 write_only 属性添加到字段中,例如密码字段在用户模型。对于不在模型上的任何字段或已经在序列化程序上明确指定的字段,它不会执行此操作。在您的情况下,您明确指定序列化程序中的 confirm_password 字段,这就是为什么它不起作用。


得到 KeyError 当尝试在序列化器上获取字段 confirm_password 的值 UserSerializer 。序列化器字段可能不正确地命名,并且不匹配 OrderedDict 实例



$ b $上的任何属性或键b

在创建的用户的重新序列化期间,当它尝试序列化您的 confirm_password 字段时,会引发这种情况。因为它不能在 User 模型中找到该字段,它会触发此错误,尝试解释问题。不幸的是,因为这是一个新的用户,它告诉你混淆地看看 OrderedDict 实例,而不是 User 实例

 类UserSerializer(serializers.ModelSerializer):
confirm_password = serializers.CharField如果您明确指定了 write_only

code>,并从您的 write_only_fields 中删除​​该字段,那么您应该会看到您期望的行为。



您可以在此链接


Situation

I am creating a simple endpoint that allows for the creation of a user. I need a field that is not in my user model (i.e., confirm_password). I will run validation that compares this field and another field that is in my model, and then never use the additional field again in the serializer.

Problem

DRF version 3 has changed the process for accomplishing this, and I do not quite understand what the documentation is suggesting I do. See here for the documentation.

Attempt at Solution

I have created a UserSerializer that looks like this:

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']

I was hoping that popping confirm_password in validate would take care of my problems, but I just get the following:

Got KeyError when attempting to get a value for field confirm_password on serializer UserSerializer. The serializer field might be named incorrectly and not match any attribute or key on the OrderedDict instance

解决方案

You are looking for a write-only field, as I'm assuming you won't want to display the password confirmation in the API. Django REST Framework introduced the write_only parameter in the 2.3.x timeline to complement the read_only parameter, so the only time validation is run is when an update is being made. The write_only_fields meta property was added around the same time, but it's important to understand how both of these work together.

The write_only_fields meta property will automatically add the write_only property to a field when it is automatically created, like for a password field on a User model. It will not do this for any fields which are not on the model, or fields that have been explicitly specified on the serializer. In your case, you are explicitly specifying the confirm_password field on your serializer, which is why it is not working.

Got KeyError when attempting to get a value for field confirm_password on serializer UserSerializer. The serializer field might be named incorrectly and not match any attribute or key on the OrderedDict instance

This is raised during the re-serialization of the created user, when it is trying to serialize your confirm_password field. Because it cannot find the field on the User model, it triggers this error which tries to explain the problem. Unfortunately because this is on a new user, it tells you to confusingly look at the OrderedDict instance instead of the User instance.

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

If you explicitly specify write_only on the serializer field, and remove the field from your write_only_fields, then you should see the behaviour your are expecting.

You can find documentation about this on this link

这篇关于Django REST框架中的其他序列化程序字段3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆