PatchModelForm - A ModelForm subclass with the semantics of the PATCH HTTP method

Use this class to partially update one or more fields of a model. Only the fields that are bound to the form via the "data" parameter in the constructor get updated. All automatically generated fields have their "required" attribute set to False.

fromdjangoimportformsfromdjango.core.exceptionsimportValidationErrorfromdjango.forms.fieldsimportFileFieldclassPatchModelForm(forms.ModelForm):def__init__(self,*args,**kwargs):forfieldnameinself.base_fields:self.base_fields[fieldname].required=Falseself.empty_permited=Truereturnsuper(UpdateModelForm,self).__init__(*args,**kwargs)def_clean_fields(self):forname,fieldinself.fields.items():# value_from_datadict() gets the data from the data dictionaries. # Each widget type knows how to retrieve its own data, because some # widgets split data over several HTML fields. value=field.widget.value_from_datadict(self.data,self.files,self.add_prefix(name))# this is the key difference with the inherited behavior so fields# not present in the bound data do not get updated with None valuesifself.add_prefix(name)notinself.data:continuetry:ifisinstance(field,FileField):initial=self.initial.get(name,field.initial)value=field.clean(value,initial)else:value=field.clean(value)self.cleaned_data[name]=valueifhasattr(self,'clean_%s'%name):value=getattr(self,'clean_%s'%name)()self.cleaned_data[name]=valueexceptValidationError,e:self._errors[name]=self.error_class(e.messages)ifnameinself.cleaned_data:delself.cleaned_data[name]