I need to add the ability to save the minimum_commission as positive number, but None is also available. I have added the serialiser:
class Appartement(models.Model):
minimum_commission = models.FloatField(null=True, default=None)
class RentalTestSerializer(serializers.ModelSerializer):
minimum_commission = serializers.FloatField(required=False, min_value=0)
class Meta:
model = Appartement
fields = (
'minimum_commission',
)
But when I pass the empty string from the form(or shell), I see the A valid number is required validation error.
In [21]: ser = RentalTestSerializer(data={'minimum_commission': ''})
In [22]: ser.is_valid()
Out[22]: False
In [23]: ser.errors
Out[23]:
ReturnDict([('minimum_commission',
[ErrorDetail(string=u'A valid number is required.', code=u'invalid')])])
At first I have added custom field: BlankableFloatField which convert empty string to the None:
class BlankableFloatField(serializers.FloatField):
"""
We wanted to be able to receive an empty string ('') or 'null' for a float field
and in that case turn it into a None number
"""
def to_internal_value(self, data):
if data in ['', 'null']:
return None
return super(BlankableFloatField, self).to_internal_value(data)
and added the custom validation:
class RentalTestSerializer(serializers.ModelSerializer):
minimum_commission = BlankableFloatField(required=False)
class Meta:
model = Appartement
fields = (
'minimum_commission',
)
def validate_minimum_commission(self, value):
if value and value < 0:
raise serializers.ValidationError(_("Minimum commission should be greater than 0"))
return value
For now it works as expected:
In [38]: ser = RentalTestSerializer(data={'minimum_commission': ''})
In [39]: ser.is_valid()
Out[39]: True
but I think is there way to do it more elegant?
as I see the main issue is into passing the empty string from the form. I need it to reset the minimum_commission column. So, the final solution is:
class Appartement(models.Model):
# I have added the blank=True and validator
minimum_commission = models.FloatField(null=True, default=None, blank=True, validators=[MinValueValidator(0.0)])
class RentalTestSerializer(serializers.ModelSerializer):
# I continue to use the custom field to transform empty space to the None
# but instead of custom validation just added the allow_null=True and min_value validator.
minimum_commission = BlankableFloatField(required=False, allow_null=True, min_value=0)
class Meta:
model = Appartement
fields = (
'minimum_commission',
)
After plaing with the solution of processing empty string I found that clearer is to skip sending empty string on front-end at all and set the default=None into serialiser. Also, the custom field is not needed anymore.
class Appartement(models.Model):
minimum_commission = models.FloatField(null=True, default=None)
class RentalTestSerializer(serializers.ModelSerializer):
minimum_commission = serializer.FloatField(required=False, allow_null=True, min_value=0, default=None)
class Meta:
model = Appartement
fields = (
'minimum_commission',
)
Like I mentioned in the comment - the appartement model would be useful.
But if I understand correctly, what you want to achieve should be quite simple as follows:
class Appartement(models.Model):
minimum_commission = models.FloatField(blank=True, null=True, default=None)
class RentalTestSerializer(serializers.ModelSerializer):
class Meta:
model = Appartement
fields = (
'minimum_commission',
)
With this implementation, minimum_commission is optional, and it accepts null values too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With