I have a model that is being shared across many different forms. An ugly side effect of this was that if I ever forgot to ensure that the HTML rendered contained *exactly* the fields defined in the form, django would overwrite the values.
Here’s a mixin that you can add to any ModelForm which will only update values.
Note that this still allows users to update a model field explicitly with a blank.
from django.forms.models import model_to_dict from django import forms class OverwriteOnlyModelFormMixin(object): ''' Delete POST keys that were not actually found in the POST dict to prevent accidental overwriting of fields due to missing POST data. ''' def clean(self): cleaned_data = super(OverwriteOnlyModelFormMixin, self).clean() for field in cleaned_data.keys(): if self.prefix is not None: post_key = '-'.join((self.prefix, field)) else: post_key = field if post_key not in self.data: # value was not posted, thus it should not overwrite any data. del cleaned_data[field] # only overwrite keys that were actually submitted via POST. model_data = model_to_dict(self.instance) model_data.update(cleaned_data) return model_data