How do I update just one field in an instance using ModelForm if the POST request has only that one field as parameter? ModelField tries to override the fields that were not passed in the POST request with None leading to loss of data.
I have a model with +25 fields say
class C(models.Model):
a = models.CharField(max_length=128)
b = models.CharField(max_length=128)
...
x = models.IntegerField()
and I have a desktop application that does POST requests in order to edit an instance of C through an exposed api method in views.py
In the api method I am using ModelForm to validate the fields as follows:
form = CModelForm(request.POST, instance=c_instance)
if form.is_valid():
form.save()
When doing save() django either complains that some other field cannot be null or (if all fields are optional) overwrites them with None.
Does somebody know how to manage it? I would do all checks manually and update manually, but the model has so freakishly long list of fields...
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.
If you need to reload a model's values from the database, you can use the refresh_from_db() method. When this method is called without arguments the following is done: All non-deferred fields of the model are updated to the values currently present in the database.
If you are extending your form from a ModelForm, use the instance keyword argument. Here we pass either an existing instance or a new one, depending on whether we're editing or adding an existing article. In both cases the author field is set on the instance, so commit=False is not required.
It also means that when Django receives the form back from the browser, it will validate the length of the data. A Form instance has an is_valid() method, which runs validation routines for all its fields. When this method is called, if all fields contain valid data, it will: return True.
Got this figured. What I do is update the request.POST dictionary with values from the instance - so that all unchanged fields are automatically present. This will do it:
from django.forms.models import model_to_dict
from copy import copy
def UPOST(post, obj):
'''Updates request's POST dictionary with values from object, for update purposes'''
post = copy(post)
for k,v in model_to_dict(obj).iteritems():
if k not in post: post[k] = v
return post
and then you just do:
form = CModelForm(UPOST(request.POST,c_instance),instance=c_instance)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With