class UserSerializer(serializers.HyperlinkedModelSerializer): password2 = serializers.CharField() class Meta: model = User fields = ('url', 'id', 'email', 'sex', 'birthday', 'name', 'password', 'password2') # read_only_fields = ('email',) write_only_fields = ('password',) def __init__(self, *args, **kwargs): # Don't pass the 'fields' arg up to the superclass fields = kwargs.pop('fields', None) # Instantiate the superclass normally super(UserSerializer, self).__init__(*args, **kwargs) if fields: # Drop any fields that are not specified in the `fields` argument. allowed = set(fields) existing = set(self.fields.keys()) for field_name in existing - allowed: self.fields.pop(field_name) def restore_object(self, attrs, instance=None): user = super(UserSerializer, self).restore_object(attrs, instance) if instance is None: user.set_password(attrs['password']) return user def to_native(self, obj): if 'password2' in self.fields: del self.fields['password2'] return super(UserSerializer, self).to_native(obj) def validate_sex(self, attrs, source): if attrs['sex'] not in (0, 1): raise serializers.ValidationError( _("You must choice '1' or '0'. '1' means male and '0' means" + " female. Your input: '%(value)s'"), code='invalid', params={'value': attrs['sex']} ) return attrs def validate_password2(self, attrs, source): # http://goo.gl/U7FGWZ if attrs.get('password') == attrs.pop('password2'): return attrs raise serializers.ValidationError( _("This field must be matched by password field"), code='password_mismatch', )