Reputation: 2657
I'm trying to write a webservice which performs inserts or updates. The request is a post with headers,value which contains table name, column name and the value to be set for each column, I'm parsing the request headers and forming a parameter dict
def handel_request(request): if request.method == "POST":
param_dict = formParmDict(request)
##if insert param_dict["Model"] is {'pk':1,'field1':100,'field2':200}
##if update param_dict["Model"] is {'pk':1,'field1':100}
Model(**param_dict["Model"]).save() ## if update then sets field2 to null
return HttpResponse()
else:
return HttpResponseBadRequest()
This works fine while the .save()
performs an insert.
In case of update ie if param_dict["Model"]
contains {pk:1, field1:somevalue}
to be updated then it sets the rest of the fields other than the ones specified in param_dict["Model"]
to null. why is that? am I doing something wrong? isn't save suppose to update only the fields specified?
Upvotes: 1
Views: 1327
Reputation: 101
Maybe you shoul use some function like this:
def insert_or_update(param_dict):
pk = param_dict.get('pk', None)
if pk:
Model.objects.filter(pk=pk).update(**param_dict)
else:
Model(**param_dict)
Model.save()
Upvotes: 0
Reputation: 48720
This is not how you're supposed to update.
Model(**param_dict["Model"]).save()
You're creating a new instance with the same id
. Instead, you should get
the instance, and then update it appropriately.
m = Model.objects.get(id=param_dict['id'])
m.field = param_dict['some_field']
m.save()
Or, you can use the Manager update method:
Model.objects.filter(id=param_dict['id']).update(**param_dict['Model'])
There's also the get_or_create method if you're not sure whether or not the record already exists.
You can try using a REST framework, like tasty-pie or django-rest-framework, which might alleviate some problems you're having.
Edit:
A brief summary about how save
works in django. This is what I meant about whether or not an INSERT
or an UPDATE
is happening. Unless your post_data
dict contains empty values for all the fields, read the documentation on how save
works for a more thorough understanding of how django works.
So, what is happening in your case is this:
dict = {'id': 1, 'field1': 'my_value'}
m = Model(**dict)
m.id # 1
m.field1 # my_value
m.field2 # None (because you haven't set it, it defaults to None
m.save() # UPDATEs the existing instance with id 1 with ALL of the values of `m`
So, you're saving an instance that contains None
values. That's why I'm suggesting you do a get
, so that all the correct values are filled, before saving to the database.
Upvotes: 2