2

i am trying to set the min_value Attribute on Form level within my modelform.

Forms.py

class ProductForm(forms.models.ModelForm):
    class Meta:
        model = Artikel
        localized_fields = '__all__'
        fields = ('price',)

Model.py

class Artikel(models.Model):
    price = models.FloatField(help_text ='Price')

How can i setup the modelform that i can constrain the values allowed on the modelform? I want the user to only enter values greater than or equal to 0.01. I dont want to restricted on Database Level cause i dont want to limit myself in that regard.

Burnie800
  • 77
  • 1
  • 9
  • @Saket this is not an exact duplicate. This question is about a ModelForm, the linked question is about a regular form. The answer for each is different. – voodoo-burger Jan 17 '17 at 15:50
  • @voodoo-burger Thanks for pointing that out. It was my mistake. I believe this should be correct. http://stackoverflow.com/questions/19489699/how-to-add-class-id-placeholder-attributes-to-a-field-in-django-model-forms – Saket Jan 17 '17 at 15:53

3 Answers3

6

You can override the ModelForm's init method. This will set the min attribute on the field to 10:

    def __init__(self, *args, **kwargs):
        super(ProductForm, self).__init__(*args, **kwargs)
        self.fields['price'].widget.attrs['min'] = 10
voodoo-burger
  • 2,123
  • 3
  • 22
  • 29
4

In addition to setting 'min' attribute on widget, also override form's clean_fieldname() method:

class ProductForm(forms.models.ModelForm):

        def __init__(self, *args, **kwargs):
            super(ProductForm, self).__init__(*args, **kwargs)
            self.fields['price'].widget.attrs['min'] = 0.01


        def clean_price(self):
            price = self.cleaned_data['price']
            if price < 0.01:
                raise forms.ValidationError("Price cannot be less than 0.01")
            return price

        class Meta:
            model = Artikel
            localized_fields = '__all__'
            fields = ('price',)

Doc says:

The clean_<fieldname>() method is called on a form subclass – where is replaced with the name of the form field attribute. This method does any cleaning that is specific to that particular attribute, unrelated to the type of field that it is. This method is not passed any parameters. You will need to look up the value of the field in self.cleaned_data and remember that it will be a Python object at this point, not the original string submitted in the form (it will be in cleaned_data because the general field clean() method, above, has already cleaned the data once).

  • The clean method is called post form submission. The Original question requests the validation to be on the client side. However your answer should be coupled with overriding ModelForm's init to provide both client and server side validation. – Saket Jan 17 '17 at 15:55
  • @AatishNeupane how is `clean_date` going to clean the price field? – voodoo-burger Jan 17 '17 at 16:40
0

The simple way to do this is to set the validator on the field and provide a custom error message:

class ProductModelForm(forms.ModelForm):
   price = forms.FloatField(min_value=0.01,
                            error_messages={'min_value': u'Price cannot be less than 0.01'}) 
Victor
  • 2,864
  • 1
  • 12
  • 20
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284