In [1]: from django.db.models import F
In [2]: from forum.models import Post
In [3]: post = Post.objects.get(id=1)
In [4]: post.view_count = F('view_count') + 1
In [5]: post.save()
In [6]: post.view_count
Out[6]: <CombinedExpression: F(view_count) + Value(1)>
In [7]: post = Post.objects.get(id=1)
In [8]: post.view_count
Out[8]: 3
After saved the post, it returned the combined expression.
I want the exact result (3).
is it possible to do without calling get method again / refresh_from_db ?
F() expressions. An F() object represents the value of a model field, transformed value of a model field, or annotated column. It makes it possible to refer to model field values and perform database operations using them without actually having to pull them out of the database into Python memory.
In the Django QuerySet API, F() expressions are used to refer to model field values directly in the database.
¶ Django allows using SQL subqueries.
Django's database functions represent functions that will run in the database. It provides a way for users to use functions provided by the underlying database as annotations, aggregations, or filters. Functions are also expressions, so they can be used and combined with other expressions like aggregate functions.
In Django 1.8+, you can use the refresh_from_db
method. It won't save any SQL queries, but you might think the code is nicer.
>>> post = Post.objects.get(id=1)
>>> post.view_count
2
>>> post.view_count = F('view_count') + 1
>>> post.save()
>>> post.refresh_from_db()
>>> post.view_count
3
Since the update happens in the database, it's not possible to get the new value in Django without doing a get()
or a refresh_from_db
(which both cause a similar SQL query). However, it is possible to avoid the initial get()
by using update()
instead.
>>> Post.objects.filter(id=1).update(view_count=F('view_count') + 1)
>>> post = Post.objects.get(id=1)
>>> post.view_count
3
From the docs https://docs.djangoproject.com/en/1.7/ref/models/queries/#f-expressions,
Python never gets to know about encapsulated SQL expression post.view_count = F('view_count') + 1 # F('view_count') Django sql expression
.
it is dealt with entirely by the database.
So changes done on Database while Python all knows about the expression you applied rather then result.
You can do it by this way directly:-
post = Post.objects.filter(id=1)
post.update(view_count = F('view_count') + 1)
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