Updating Records (update, save, F expressions)
Update records by modifying and calling save(), or use QuerySet.update() for bulk updates. F expressions let you perform atomic database-level updates without race conditions — essential for counters and computed fields.
15 min•By Priygop Team•Updated 2026
Update Methods
- obj.field = value; obj.save() — Update single object
- obj.save(update_fields=['field']) — Only update specified fields
- QuerySet.update(field=value) — Bulk update (no save() called)
- F('field') — Reference field value in database, not Python
- F expressions prevent race conditions in concurrent updates
- update() returns the number of rows affected
- save() triggers signals; update() does NOT
Update Examples
Update Examples
# blog/views.py
# from django.db.models import F
# Method 1: Modify and save
# post = Post.objects.get(pk=1)
# post.title = 'Updated Title'
# post.save()
# Save only specific fields (efficient)
# post.title = 'New Title'
# post.save(update_fields=['title'])
# Method 2: Bulk update — one SQL query
# Post.objects.filter(published=False).update(published=True)
# # UPDATE blog_post SET published=True WHERE published=False
# F expressions — atomic database operations
# post = Post.objects.get(pk=1)
# post.views_count = F('views_count') + 1
# post.save()
# # SQL: UPDATE SET views_count = views_count + 1
# Why F() matters — preventing race conditions:
# BAD (race condition):
# post.views_count = post.views_count + 1 # Reads Python value
# post.save() # Another request might have changed it!
# GOOD (atomic):
# post.views_count = F('views_count') + 1 # Database handles it
# post.save()
# Bulk with F()
# Post.objects.filter(published=True).update(
# views_count=F('views_count') + 1
# )Tip
Tip
Add widgets to customize form rendering: forms.Textarea(attrs={'rows': 4, 'class': 'form-control'}) for Bootstrap styling.
Diagram
Loading diagram…
QuerySets are LAZY — no DB hit until evaluated.
Common Mistake
Warning
Not setting widget attrs for styling. Default form rendering looks plain. Add CSS classes via widget attrs dict.
Practice Task
Note
(1) Add Bootstrap classes via widget attrs. (2) Customize labels and help_text. (3) Add placeholder text.
Quick Quiz
Key Takeaways
- Update records by modifying and calling save(), or use QuerySet.
- obj.field = value; obj.save() — Update single object
- obj.save(update_fields=['field']) — Only update specified fields
- QuerySet.update(field=value) — Bulk update (no save() called)