views:

73

answers:

2

Hello guys, after doing a query with F() (see http://docs.djangoproject.com/en/dev/topics/db/queries/#query-expressions), I save the object, but then, I need to save it again. I want to remove F() from the field. If I don't, F() gets called again.

For example

rank.ammountMatchesRanked = F('ammountMatchesRanked') + 1
rank.save() # does ammountMatchesRanked = ammountMatchesRanked + 1
... # Manipulating more rank fields (can't manipulate before)
rank.save() # does ammountMatchesRanked++ again (undesired)

Any idea on how can I clear reference fields? I have searched the documentation but I didn't find it.

Thanks in advance

+1  A: 

i am not that good in django, but what about doing this:

rank.ammountMatchesRanked = F('ammountMatchesRanked');

just before the second call?

dusoft
Hey dusoft, this worked, thanks! Before marking you as accepted solution I will wait to see if anyone has a better way. Doing what you suggested is probably inserting something like SET ammountMatchesRanked=ammountMatchesRanked on the update query, which is unnecessary
Clash
is there option to `unset(rank.ammountMatchesRanked)` ?
dusoft
I'm afraid that's not possible
Clash
+1  A: 

Why are you using F() here at all? F is really for use within queries, where you want to just get those objects who have a certain property with some relation to another property in the same model. Once you've got the object, there's no need to use it - you can just do it in standard Python:

rank.ammountMatchesRanked += 1
rank.save()

Edited after comment No, you have misunderstood what lazy loading is. It applies to instances (ie database rows) within a queryset, not fields (ie columns) within an instance. So once you have accessed an instance at all, Django by default will load all its fields (except those you have marked with defer()), so the above will not result in an extra query.

The documentation for using F() in updates which you linked to explains that this is only if you're not doing anything else with the object. You are, so this is not an optimisation.

Daniel Roseman
No, it's not only for that use. Checkhttp://docs.djangoproject.com/en/dev/ref/models/instances/#updating-attributes-based-on-existing-fieldsIf I do `rank.ammountMatchesRanked += 1` it will access the value of `ammountMatchesRanked`, resulting in an additional query. The object hasn't been used before. Django uses a lazy mechanism which will only query when you actually use the object.
Clash
No, see my further explanation above.
Daniel Roseman
I haven't accessed any field at all yet, so the query to select the row has not been ran yet. The first action I'm doing is `rank.ammountMatchesRanked = F('ammountMatchesRanked') + 1` `rank.save()`
Clash
But you *will* - you go on to do more manipulations after the first save(). This means that you actually do *more* database calls than necessary - the opposite of what you intended. Normally you would only do one UPDATE, your way you are doing at least two.
Daniel Roseman
I see Daniel... anyways, my question wasn't really answered yet, is there any way to remove the F() from the field, or remove the field from future queries? Thanks
Clash