Reputation: 33405
I recently asked this question and solved my problem as originally stated. The following code works:
class FloatRangeField (FloatField):
"""A FloatField constrained to a given range."""
def __init__ (self, minimum, maximum, **kwargs):
minmax = [MinValueValidator (minimum), MaxValueValidator (maximum)]
self.minimum = minimum
self.maximum = maximum
kwargs ['validators'] = minmax
FloatField.__init__ (self, **kwargs)
def deconstruct (self):
name, path, args, kwargs = super () .deconstruct ()
kwargs ['minimum'] = self.minimum
kwargs ['maximum'] = self.maximum
del kwargs ['validators']
return name, path, args, kwargs
class AffinityField (FloatRangeField):
"""An affinity is a float from -1 (hate) to +1 (love)."""
def __init__ (self, **kwargs):
FloatRangeField.__init__ (self, -1.0, 1.0, **kwargs)
def deconstruct (self):
name, path, args, kwargs = super () .deconstruct ()
del kwargs ['minimum']
del kwargs ['maximum']
return name, path, args, kwargs
However, I don't believe this is quite complete. I am new to Django, but my understanding is that adding validators constrains the data that the model is willing to save, but separately from this, as this answer indicates, there is validation at the form level.
If you need constraint on form level you can pass min_value and max_value to form field:
myfloat = forms.FloatField(min_value=0.0, max_value=1.0)
I don't have any visible forms yet (just starting to learn!) so I don't know if it is necessary to do this separately, but from the sounds of it I do have to pass min_value
and max_value
as well as the validator objects. Here is my attempt:
class FloatRangeField (FloatField):
"""A FloatField constrained to a given range."""
def __init__ (self, minimum, maximum, **kwargs):
minmax = [MinValueValidator (minimum), MaxValueValidator (maximum)]
self.minimum = minimum
self.maximum = maximum
# Validators for the model
kwargs ['validators'] = minmax
# Arguments for the form validation
kwargs ['min_value'] = minimum
kwargs ['max_value'] = maximum
FloatField.__init__ (self, **kwargs)
def deconstruct (self):
name, path, args, kwargs = super () .deconstruct ()
kwargs ['minimum'] = self.minimum
kwargs ['maximum'] = self.maximum
del kwargs ['validators']
del kwargs ['min_value']
del kwargs ['max_value']
return name, path, args, kwargs
This throws an exception:
FloatField.__init__ (self, **kwargs)
TypeError: __init__() got an unexpected keyword argument 'min_value'
But according to the documentation, the min_value
argument is expected, so I don't know what this error really means.
I thought I understood the principle of field deconstructors (delete from kwargs
those things which you don't need as inputs when you define them in the child class's __init__
) but perhaps not.
What's wrong with how I'm using min_value
and max_value
?
Upvotes: 0
Views: 3636
Reputation: 47354
Looks like you mixed form fields and model fields. Link you provided in your question described form's FloatField
.
But model's FloatField
which you are trying to customize doesn't have min_value
and max_value
arguments by default.
Upvotes: 3