Back to Articles
2024-02-22

Avoiding Race Conditions with F() Expressions

A common mistake in Django is updating a value by fetching it into memory, changing it, and saving it. `F()` expressions solve this by generating a SQL query that updates the field relative to its current value in the database.

Scenario 1: Atomic Increment

Increase a counter safely without race conditions.

python
from django.db.models import F

# The DB handles the math: UPDATE table SET views = views + 1
Post.objects.filter(id=1).update(views=F('views') + 1)

Scenario 2: Comparing Fields

Find records where one column is greater than another column.

python
# Find orders where shipping cost is higher than product cost
expensive_shipping = Order.objects.filter(shipping_cost__gt=F('product_cost'))