Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if a field has changed in a Django modelform

I was surprised that this was difficult to do. However I came up with this, which seems to work at least for my simple case. Can anyone recommend a better approach?

def field_changed(self, fieldname):
    """Tests if the value of the field changed from the original data"""
    orig_value = self.fields[fieldname].initial or getattr(self.instance, field, None)
    orig_value = getattr(orig_value, 'pk', orig_value)
    if type(orig_value) is bool:
        # because None and False can be interchangeable
        return bool(self.data.get(fieldname)) != bool(orig_value)
    else:
        return unicode(self.data.get(fieldname)) != unicode(orig_value)
like image 482
Peter Hollingsworth Avatar asked Mar 08 '16 22:03

Peter Hollingsworth


People also ask

When saving How can you check if a field has changed django?

To check if a field has changed when saving with Python Django, we can override the `init method of the model class to keep a copt of the original value. to add the __init__ method that sets the __original_name variable to self.name to keep the original name value.

What is form Is_valid () in django?

The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class. It returns True if data is valid and place all data into a cleaned_data attribute.

How do you exclude a specific field from a ModelForm?

Set the exclude attribute of the ModelForm 's inner Meta class to a list of fields to be excluded from the form.

How do I update a specific field in django?

Use update_fields in save() If you would like to explicitly mention only those columns that you want to be updated, you can do so using the update_fields parameter while calling the save() method. You can also choose to update multiple columns by passing more field names in the update_fields list.


3 Answers

Form contains a property changed_data which holds a list of all the fields whose values have changed.

Try:

'fieldname' in myforminstance.changed_data
like image 72
Airs Avatar answered Sep 21 '22 15:09

Airs


It seems that you have reinvented .has_changed() method.

like image 35
alTus Avatar answered Sep 18 '22 15:09

alTus


Extending on Airs's answer, for multiple fields:

In a scenario where you'd like to track changes for a list of fields ['field_a', 'field_b', 'field_c']


If you'd like to check if any of those fields has changed:

any(x in myforminstance.changed_data for x in ['field_a', 'field_b', 'field_c'])

If you'd like to check if all of those fields have changed:

all(x in myforminstance.changed_data for x in ['field_a', 'field_b', 'field_c'])
like image 30
evantkchong Avatar answered Sep 17 '22 15:09

evantkchong