chidimo
chidimo

Reputation: 2948

Set value of a model field that is not part of model form

I have a model like this

class Income(models.Model):
    value = models.DecimalField(max_digits=10, decimal_places=2)
    remitted = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)

I have a form like this

class EditIncomeForm(forms.ModelForm):
    class Meta:
        model = Income
        fields = ("value", )

        def clean_value(self):
           value = self.cleaned_data["value"]
            if self.value < self.remitted:
                raise forms.ValidationError("Error message")
            return value

Now in the modelform, how do I update the value of the remitted field? I can't seem to be able to access the remitted field this way. I'm on Django 2.0

Upvotes: 1

Views: 281

Answers (2)

chidimo
chidimo

Reputation: 2948

I did some reading about Validation on a ModelForm from the docs and finally I was able to raise the error in the form. Full form code below.

This section in particular proved to be what I needed. It says:

A model form instance attached to a model object will contain an instance attribute that gives its methods access to that specific model instance.

class EditIncomeForm(forms.ModelForm):
    class Meta:
        model = Income
        fields = ("value", )

    def clean(self):
        value = self.cleaned_data['value']
        remitted = self.instance.remitted # access other model field.
        if value <= remitted:
            self.add_error("value", "Error message.")

Upvotes: 0

Daniel Roseman
Daniel Roseman

Reputation: 599490

This doesn't have anything to do with whether the field is on the form or not.

You're doing two things wrong; firstly, you're trying to access self.remitted instead of self.cleaned_data['remitted']; and secondly, remitted won't have been cleaned at the point that clean_value is called.

To access data from multiple fields, override the main clean() method instead:

 def clean(self):
      value = self.cleaned_data["value"]
      remitted = self.cleaned_data["remitted"]
      if value < remitted:
          self.add_error("value", "Error message")

Upvotes: 2

Related Questions