32👍
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 fieldconfirm_password
on serializerUserSerializer
. The serializer field might be named incorrectly and not match any attribute or key on theOrderedDict
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
0👍
Also useful for nested serializer implementation representing models, when the root model doesn’t have directly access to fields you want to use.
Thank you @vyscond 😉
Fyi here is my case:
models.py
class Company(models.Model):
permission_classes = (
IsCompanyMember,
)
name = models.CharField(
unique=True,
max_length=100,
verbose_name='company name',
null=False
)
class Profile(models.Model):
company = models.ForeignKey(Company, on_delete=models.CASCADE, null=True)
user = models.OneToOneField(User, on_delete=models.CASCADE)
is_company_admin = models.BooleanField(default=False, null=False)
is_email_validated = models.BooleanField(default=False, null=False)
is_approved_by_company_admin = models.BooleanField(default=False, null=False)
serializer.py
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = Company
fields = ('name',)
class CustomUserRegistrationSerializer(serializers.ModelSerializer):
password = serializers.CharField(style={'input_type': 'password'},
write_only=True,
validators=settings.get('PASSWORD_VALIDATORS'))
company = CompanySerializer(allow_null=False, required=True,write_only=True)
class Meta:
model = User
fields = ('username',
'email',
'password',
'company',
'first_name',
'last_name')
- Rendering individual fields in template in a custom form
- Django models across multiple projects/microservices. How to?