Django REST框架中的其他序列化程序字段3 [英] Additional Serializer Fields in Django REST Framework 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
的值rializerOrderedDict
实例
你正在寻找一个只写字段,因为我假设你不想在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屋!