Get the latest record with filter in Django
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
To get the latest record that matches a filter in Django, you usually combine filter() with an ordering field such as created_at, updated_at, or an auto-incrementing primary key. The main decision is whether you want an exception when no record matches or a quiet None. Django supports both patterns, and choosing the right one keeps the query behavior explicit.
Use filter(...).order_by(...).first()
The most common pattern is to sort the filtered rows in descending order and take the first result. This is readable and returns None when no row matches.
This is usually the best default because it handles the empty case safely without raising an exception.
Use latest() When No Match Should Be Exceptional
Django also provides latest(), which returns one object ordered by the given field. Unlike first(), it raises DoesNotExist if the queryset is empty.
This is a good choice when the absence of a record is abnormal and should be handled explicitly.
Define a Default Latest Field in the Model
If the same model is often queried for its latest row, you can define get_latest_by in Meta. That allows latest() to be called without repeating the field name everywhere.
Then the query becomes:
This keeps the code concise, but it only makes sense if one field is the clear definition of "latest" across the model.
Pick the Right Ordering Field
The query is only as correct as the field you sort by. If "latest" means most recently created, use a creation timestamp. If it means most recently updated, use an update timestamp. If the primary key is monotonically increasing and creation order is sufficient, ordering by -id can also work.
This can be fine for simple tables, but timestamps are usually clearer and more portable as business logic.
Make the Query Efficient
Filtering and ordering can be expensive on large tables if the relevant fields are not indexed. If the query is common, consider database indexes on the filtering columns and the ordering column.
For example, if the app frequently asks for the latest paid invoice by customer, an index strategy should support both customer_id, status, and the sort field. The exact best index depends on the database, but the principle is stable: frequent filtered-ordering queries deserve indexing attention.
Beware of Ambiguous Ties
Two rows can share the same timestamp. If that matters, add a second ordering key so the result is deterministic.
This avoids edge cases where two records have the same created_at down to the stored precision.
Common Pitfalls
- Calling
latest()without handling the possibility that no records match. - Ordering by the wrong field and getting the latest updated record when the business rule meant latest created record.
- Assuming
idalways represents business recency in systems with data imports or migrations. - Ignoring tie-breaking when timestamps can repeat.
- Forgetting database indexes on fields used repeatedly for filtering and ordering.
Summary
- The safest default is usually
filter(...).order_by("-field").first(). - Use
latest("field")when an empty result should raise an exception. - Define
get_latest_bywhen one field consistently defines recency for the model. - Choose the ordering field based on business meaning, not convenience alone.
- Add indexes and deterministic tie-breakers for production queries.

