how do I update only specific fields in model

3,867 views
Skip to first unread message

Josh

unread,
Jul 27, 2011, 7:53:52 AM7/27/11
to django...@googlegroups.com
I want to update only specific fields in a model and keep the old values in other fields. I've been working on this for a few days but I run out of possible solutions.As far as I can see from the documentation and internet  there isn't an easy solution to do this.  I'm new at Django, so I might overlook the obvious.  

Ticket https://code.djangoproject.com/ticket/4102 seems to indicate that this is an issue. I'm too inexperienced with django to try patching it and I prefer another way using standard Django 1.3

I've tried the following:

* .add() only inserts the new data and existing fields are overwritten and 'NULL' in the database
* do it through .update() in query using the following procedure and pseudo code.
1. the id of the record is not known. Create a queryset .objects.all() and store all id's as values in a dictionary with another unique in the model as a key to retrieve the matching id. At first I used the other unique CharField as a PK, but that gave errors in Postgres
2. Using the samples in the query-documentation. Create another query to get a single object in a queryset using:
n = SomeModel.objects.get(id=myid)
Somemodel.objects.filter(pk=n).update(somefield=newfielddata)
m.save()
This creates errors, so that doesn't work either.

I was thinking to try a different approach. When a record exists, retrieve all existing data and add this to the .save(). This seems like a pretty cumbersome way to achieve updating a few fields. What is the best way to achieve this?






Daniel Roseman

unread,
Jul 27, 2011, 8:13:46 AM7/27/11
to django...@googlegroups.com
It's not at all clear what your problem is. Obviously, updating a field in a model is something we all do all the time. Your question doesn't say what's wrong with just doing:

    obj = MyModel.objects.get(criteria=whatever)
    obj.myfield = mynewvalue
    obj.save()

--
DR.
 

Josh

unread,
Jul 27, 2011, 8:47:46 AM7/27/11
to django...@googlegroups.com
You already gave the answer. I just tried your solution and it worked.  I was trying a wrong approach and was making it much more complex than it really is. My approach caused existing values to be overwritten by Null-values and only inserting the new values.

Thanks for answering a newbie question.

bruno desthuilliers

unread,
Jul 27, 2011, 10:03:56 AM7/27/11
to Django users
On Jul 27, 1:53 pm, Josh <jos.carpente...@yahoo.com> wrote:

Daniel already answered, just a couple observations:

> 1. the id of the record is not known.

Given your question ("update (...) fields in a model", which I assume
mean : "update (...) fields in a model _instance_"), you obviously
know the pk either directly (passed as argument etc), indirectly (you
have some lookup that will retrieve the model instance), or of course
thru the instance itself (if you already have it).

> 2. Using the samples in the query-documentation. Create another query to get
> a single object in a queryset using:

> n = SomeModel.objects.get(id=myid)
> Somemodel.objects.filter(pk=n).update(somefield=newfielddata)

the "pk" lookup shortcut expected a litteral value, not a model
instance, so, assuming your model's id field is the pk (which is
usually the case), this should be:

n = SomeModel.objects.get(id=myid)
Somemodel.objects.filter(pk=n.id).update(somefield=newfielddata)

which is a overcomplicated (and rather inefficient) way to write:

Somemodel.objects.filter(pk=myid).update(somefield=newfielddata)

> m.save()

Did you mean 'n' ? If yes, a call to n.save() at this point will
overwrite the previous update.



> I was thinking to try a different approach. When a record exists, retrieve
> all existing data and add this to the .save(). This seems like a pretty
> cumbersome way to achieve updating a few fields.

Indeed !-)

> What is the best way to
> achieve this?

Depends on quite a few things. Queryset.update is atomic - which can
avoids some problems with concurrent access - and is quite fast. OTHO,
it won't trigger the pre_save and post_save signals, nor even call on
your model's save method, so if your code relies on either a custom
save method and/or pre/post save signals, you might screw it up.

Most often, you'll be safer using Daniel's solution for most things
and only using Queryset.update for batch updates if and when you know
you don't have any python code triggered by yourmodel.save()

Josh

unread,
Jul 27, 2011, 11:38:02 AM7/27/11
to django...@googlegroups.com
Thanks for the replys. The more I learn about Django, the more I start to apreciate it. I still have a lot to learn, but compared with Drupal I already feel more comfortable about Django because there is much more control. 

This is my second Django week, but sometimes I seem to get stuck at simple things because I don't quite understand how Django work internally. I really apreciate the effort taken to answeri silly questions ;-)


Reply all
Reply to author
Forward
0 new messages