← all lessons

dailyfeed · 2026-04-27 · djangomodelsorm

QuerySet.update() vs instance.save()

The idea

Django gives you two ways to change rows in the database:

The choice isn't about performance — it's about whether you want the lifecycle to run. If your save() validates, normalizes, or has side effects you don't want repeated for a narrow state change, .update() is the right tool.

How it shows up

In this repo, UserFeed.save() re-validates the URL and raises ValueError on bad input. When crawl_feed records "I just fetched this," it only wants to bump scheduling fields — re-running URL validation would be wrong:

UserFeed.objects.filter(pk=feed.pk).update(
    last_fetched_at=fetched_at,
    next_check_at=fetched_at + HEALTHY_INTERVAL,
)

A trap: .update() does not update auto_now fields. If you rely on updated_at being touched, use .save() or set it manually.

Read more

Exercises

  1. Find a .save() you could replace with .update() — pick one in this repo where only one or two fields change and the model's save() lifecycle is irrelevant. Write down what you'd lose by switching (signals? auto_now?). Done when: you have a one-paragraph note in this file describing the trade-off for that specific call site.
  2. Trigger the trap — in a Django shell, set auto_now=True on a field, then .update() a different field. Confirm the auto_now field is not refreshed. Done when: you can explain why auto_now and .update() don't mix in one sentence.