Django — Prevent ModelForm from updating values if user did not submit them

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
Advertisements

One thought on “Django — Prevent ModelForm from updating values if user did not submit them

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s