Table of Content
- How to Use F() Expressions in List of Objects
- How to Use F() Expressions in a Single Object
- How to Use F() Expressions to Annotate Data
- How to Use F() Expressions to Filter Data
- Drawback of Using F() Expressions in Django
- Wrap Off
The F() expressions in Django are very important additions that most people tend to ignore.
When working with the Django Query Set API, the F() expressions can be used to refer to model field values directly in the database.
Let's say you have a Book
class with a quantity
field, and you want to increase the quantity of the books by 50%.
One solution that most people often use is:
books = Book.objects.all()
for book in books:
book.quantity *= 1.5
book.save()
This solution, although it is possible and works, it can be replaced with an F() expression.
With an F() expression, the query can be updated in a single query.
How to Use F() Expressions in List of Objects
from django.db.models import F
Book.objects.update(quantity=F('quantity') * 1.5)
How to Use F() Expressions in a Single Object
You can also do it for a single object:
book = Book.objects.get(id=10)
book.quantity = F('quantity') * 1.5
book.save()
How to Use F() Expressions to Annotate Data
Here's how you can use F() expression to carry out data annotations.
from django.db.models import ExpressionWrapper
Book.objects.all().annotate(
value_in_stock=ExpressionWrapper(
F('quantity') * F('label'), output_field=IntegerField()
)
)
Since quantity is an IntegerField
and stock is a IntegerField
, we need to wrap the expression inside a ExpressionWrapper
object.
How to Use F() Expressions to Filter Data
Here's how it can be used to filter data as well:
Book.objects.filter(label__gte=F('ordered'))
Drawback of Using F() Expressions in Django
Before using this method in your project, you should know that the F() object persist after saving the model.
For instance:
book.quantity # quantity = int(10)
book.quantity = F('quantity') + 1
book.save() # quantity = int('11')
book.name = 'Testing F'
book.save() # quantity = int(12.00)
So, basically after updating a field like that, book.quantity
will hold an instance of django.db.models.expressions.CombinedExpression
, instead of the actual result. If you want to access the result immediately:
book.quantity = F('quantity') + 1
book.save()
print(book.quantity) # <CombinedExpression: F(quantity) + Value(1)>
book.refresh_from_db()
print(book.quantity) # int(13)
Wrap Off
There you have it! I hope you found this post useful somehow.
If you have any questions or need clarification, feel free to reach out to me.
If you learned from this tutorial, or it helped you in any way, please consider sharing and subscribing to our newsletter.