The Django Book

Appendix C: Database API Reference

Django’s database API is the other half of the model API discussed in Appendix B. Once you’ve defined a model, you’ll use this API any time you need to access the database. You’ve seen examples of this API in use throughout the book; this appendix explains all the various options in detail.

Like the model APIs discussed in Appendix B, though these APIs are considered very stable, the Django developers consistently add new shortcuts and conveniences. It’s a good idea to always check the latest documentation online, available at

Throughout this reference, we’ll refer to the following models, which might form a simple Weblog application:

from django.db import models

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def __str__(self):

class Author(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()

    def __str__(self):

class Entry(models.Model):
    blog = models.ForeignKey(Blog)
    headline = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateTimeField()
    authors = models.ManyToManyField(Author)

    def __str__(self):
        return self.headline

Creating Objects

To create an object, instantiate it using keyword arguments to the model class, and then call save() to save it to the database:

>>> from import Blog
>>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')

This performs an INSERT SQL statement behind the scenes. Django doesn’t hit the database until you explicitly call save().

The save() method has no return value.

To create an object and save it all in one step see the create manager method discussed shortly.

What Happens When You Save?

When you save an object, Django performs the following steps:

  1. Emit a pre_save signal. This provides a notification that an object is about to be saved. You can register a listener that will be invoked whenever this signal is emitted. These signals are still in development and weren’t documented when this book went to press; check the online documentation for the latest information.

  2. Preprocess the data. Each field on the object is asked to perform any automated data modification that the field may need to perform.

    Most fields do no preprocessing — the field data is kept as is. Preprocessing is only used on fields that have special behavior, like file fields.

  3. Prepare the data for the database. Each field is asked to provide its current value in a data type that can be written to the database.

    Most fields require no data preparation. Simple data types, such as integers and strings, are “ready to write” as a Python object. However, more complex data types often require some modification. For example, DateFields use a Python datetime object to store data. Databases don’t store datetime objects, so the field value must be converted into an ISO-compliant date string for insertion into the database.

  4. Insert the data into the database. The preprocessed, prepared data is then composed into an SQL statement for insertion into the database.

  5. Emit a post_save signal. As with the pre_save signal, this is used to provide notification that an object has been successfully saved. Again, these signals are not yet documented.

Autoincrementing Primary Keys

For convenience, each model is given an autoincrementing primary key field named id unless you explicitly specify primary_key=True on a field (see the section titled “AutoField” in Appendix B).

If your model has an AutoField, that autoincremented value will be calculated and saved as an attribute on your object the first time you call save():

>>> b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.')
>>>     # Returns None, because b doesn't have an ID yet.

>>>     # Returns the ID of your new object.

There’s no way to tell what the value of an ID will be before you call save(), because that value is calculated by your database, not by Django.

If a model has an AutoField but you want to define a new object’s ID explicitly when saving, just define it explicitly before saving, rather than relying on the autoassignment of the ID:

>>> b3 = Blog(id=3, name='Cheddar Talk', tagline='Thoughts on cheese.')

If you assign auto-primary-key values manually, make sure not to use an already existing primary key value! If you create a new object with an explicit primary key value that already exists in the database, Django will assume you’re changing the existing record rather than creating a new one.

Given the preceding 'Cheddar Talk' blog example, this example would override the previous record in the database:

>>> b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.')
>>>  # Overrides the previous blog with ID=3!

Explicitly specifying auto-primary-key values is mostly useful for bulk-saving objects, when you’re confident you won’t have primary key collision.

Saving Changes to Objects

To save changes to an object that’s already in the database, use save().

Given a Blog instance b5 that has already been saved to the database, this example changes its name and updates its record in the database:

>>> = 'New name'

This performs an UPDATE SQL statement behind the scenes. Again, Django doesn’t hit the database until you explicitly call save().

How Django Knows When to UPDATE and When to INSERT

You may have noticed that Django database objects use the same save() method for creating and changing objects. Django abstracts the need to use INSERT or UPDATE SQL statements. Specifically, when you call save(), Django follows this algorithm:

  • If the object’s primary key attribute is set to a value that evaluates to True (i.e., a value other than None or the empty string), Django executes a SELECT query to determine whether a record with the given primary key already exists.
  • If the record with the given primary key does already exist, Django executes an UPDATE query.
  • If the object’s primary key attribute is not set, or if it’s set but a record doesn’t exist, Django executes an INSERT.

Because of this, you should be careful not to specify a primary key value explicitly when saving new objects if you cannot guarantee the primary key value is unused.

Updating ForeignKey fields works exactly the same way; simply assign an object of the right type to the field in question:

>>> joe = Author.objects.create(name="Joe")
>>> = joe

Django will complain if you try to assign an object of the wrong type.

Retrieving Objects

Throughout the book you’ve seen objects retrieved using code like the following:

>>> blogs = Blog.objects.filter(author__name__contains="Joe")

There are quite a few “moving parts” behind the scenes here: when you retrieve objects from the database, you’re actually constructing a QuerySet using the model’s Manager. This QuerySet knows how to execute SQL and return the requested objects.

Appendix B looked at both of these objects from a model-definition point of view; now we’ll look at how they operate.

A QuerySet represents a collection of objects from your database. It can have zero, one, or many filters — criteria that narrow down the collection based on given parameters. In SQL terms, a QuerySet equates to a SELECT statement, and a filter is a limiting clause such as WHERE or LIMIT.

You get a QuerySet by using your model’s Manager. Each model has at least one Manager, and it’s called objects by default. Access it directly via the model class, like so:

>>> Blog.objects
<django.db.models.manager.Manager object at 0x137d00d>

Managers are accessible only via model classes, rather than from model instances, to enforce a separation between “table-level” operations and “record-level” operations:

>>> b = Blog(name='Foo', tagline='Bar')
>>> b.objects
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: Manager isn't accessible via Blog instances.

The Manager is the main source of QuerySets for a model. It acts as a “root” QuerySet that describes all objects in the model’s database table. For example, Blog.objects is the initial QuerySet that contains all Blog objects in the database.

Caching and QuerySets

Each QuerySet contains a cache, to minimize database access. It’s important to understand how it works, in order to write the most efficient code.

In a newly created QuerySet, the cache is empty. The first time a QuerySet is evaluated — and, hence, a database query happens — Django saves the query results in the QuerySet‘s cache and returns the results that have been explicitly requested (e.g., the next element, if the QuerySet is being iterated over). Subsequent evaluations of the QuerySet reuse the cached results.

Keep this caching behavior in mind, because it may bite you if you don’t use your QuerySet``s correctly. For example, the following will create two ``QuerySets, evaluate them, and throw them away:

print [e.headline for e in Entry.objects.all()]
print [e.pub_date for e in Entry.objects.all()]

That means the same database query will be executed twice, effectively doubling your database load. Also, there’s a possibility the two lists may not include the same database records, because an Entry may have been added or deleted in the split second between the two requests.

To avoid this problem, simply save the QuerySet and reuse it:

queryset = Poll.objects.all()
print [p.headline for p in queryset] # Evaluate the query set.
print [p.pub_date for p in queryset] # Reuse the cache from the evaluation.

Filtering Objects

The simplest way to retrieve objects from a table is to get all of them. To do this, use the all() method on a Manager:

>>> Entry.objects.all()

The all() method returns a QuerySet of all the objects in the database.

Usually, though, you’ll need to select only a subset of the complete set of objects. To create such a subset, you refine the initial QuerySet, adding filter conditions. You’ll usually do this using the filter() and/or exclude() methods:

>>> y2006 = Entry.objects.filter(pub_date__year=2006)
>>> not2006 = Entry.objects.exclude(pub_date__year=2006)

filter() and exclude() both take field lookup arguments, which are discussed in detail shortly.

Chaining Filters

The result of refining a QuerySet is itself a QuerySet, so it’s possible to chain refinements together, for example:

>>> qs = Entry.objects.filter(headline__startswith='What')
>>> qs = qs..exclude(
>>> qs = qs.filter(pub_date__gte=datetime.datetime(2005, 1, 1))

This takes the initial QuerySet of all entries in the database, adds a filter, then an exclusion, and then another filter. The final result is a QuerySet containing all entries with a headline that starts with “What” that were published between January 1, 2005, and the current day.

It’s important to point out here that QuerySets are lazy — the act of creating a QuerySet doesn’t involve any database activity. In fact, the three preceding lines don’t make any database calls; you can chain filters together all day long and Django won’t actually run the query until the QuerySet is evaluated.

You can evaluate a QuerySet in any following ways:

  • Iterating: A QuerySet is iterable, and it executes its database query the first time you iterate over it. For example, the following QuerySet isn’t evaluated until it’s iterated over in the for loop:

    qs = Entry.objects.filter(pub_date__year=2006)
    qs = qs.filter(headline__icontains="bill")
    for e in qs:
        print e.headline

    This prints all headlines from 2006 that contain “bill” but causes only one database hit.

  • Printing it: A QuerySet is evaluated when you call repr() on it. This is for convenience in the Python interactive interpreter, so you can immediately see your results when using the API interactively.

  • Slicing: As explained in the upcoming “Limiting QuerySets” section, a QuerySet can be sliced using Python’s array-slicing syntax. Usually slicing a QuerySet returns another (unevaluated)``QuerySet``, but Django will execute the database query if you use the “step” parameter of slice syntax.

  • Converting to a list: You can force evaluation of a QuerySet by calling list() on it, for example:

    >>> entry_list = list(Entry.objects.all())

    Be warned, though, that this could have a large memory overhead, because Django will load each element of the list into memory. In contrast, iterating over a QuerySet will take advantage of your database to load data and instantiate objects only as you need them.

Filtered QuerySets Are Unique

Each time you refine a QuerySet, you get a brand-new QuerySet that is in no way bound to the previous QuerySet. Each refinement creates a separate and distinct QuerySet that can be stored, used, and reused:

q1 = Entry.objects.filter(headline__startswith="What")
q2 = q1.exclude(
q3 = q1.filter(

These three QuerySets are separate. The first is a base QuerySet containing all entries that contain a headline starting with “What”. The second is a subset of the first, with an additional criterion that excludes records whose pub_date is greater than now. The third is a subset of the first, with an additional criterion that selects only the records whose pub_date is greater than now. The initial QuerySet (q1) is unaffected by the refinement process.

Limiting QuerySets

Use Python’s array-slicing syntax to limit your QuerySet to a certain number of results. This is the equivalent of SQL’s LIMIT and OFFSET clauses.

For example, this returns the first five entries (LIMIT 5):

>>> Entry.objects.all()[:5]

This returns the sixth through tenth entries (OFFSET 5 LIMIT 5):

>>> Entry.objects.all()[5:10]

Generally, slicing a QuerySet returns a new QuerySet — it doesn’t evaluate the query. An exception is if you use the “step” parameter of Python slice syntax. For example, this would actually execute the query in order to return a list of every second object of the first ten:

>>> Entry.objects.all()[:10:2]

To retrieve a single object rather than a list (e.g., SELECT foo FROM bar LIMIT 1), use a simple index instead of a slice. For example, this returns the first Entry in the database, after ordering entries alphabetically by headline:

>>> Entry.objects.order_by('headline')[0]

This is roughly equivalent to the following:

>>> Entry.objects.order_by('headline')[0:1].get()

Note, however, that the first of these will raise IndexError while the second will raise DoesNotExist if no objects match the given criteria.

Query Methods That Return New QuerySets

Django provides a range of QuerySet refinement methods that modify either the types of results returned by the QuerySet or the way its SQL query is executed. These methods are described in the sections that follow. Some of the methods take field lookup arguments, which are discussed in detail a bit later on.


Returns a new QuerySet containing objects that match the given lookup parameters.


Returns a new QuerySet containing objects that do not match the given lookup parameters.


By default, results returned by a QuerySet are ordered by the ordering tuple given by the ordering option in the model’s metadata (see Appendix B). You can override this for a particular query using the order_by() method:

>> Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')

This result will be ordered by pub_date descending, then by headline ascending. The negative sign in front of "-pub_date" indicates descending order. Ascending order is assumed if the - is absent. To order randomly, use "?", like so:

>>> Entry.objects.order_by('?')

Returns a new QuerySet that uses SELECT DISTINCT in its SQL query. This eliminates duplicate rows from the query results.

By default, a QuerySet will not eliminate duplicate rows. In practice, this is rarely a problem, because simple queries such as Blog.objects.all() don’t introduce the possibility of duplicate result rows.

However, if your query spans multiple tables, it’s possible to get duplicate results when a QuerySet is evaluated. That’s when you’d use distinct().


Returns a special QuerySet that evaluates to a list of dictionaries instead of model-instance objects. Each of those dictionaries represents an object, with the keys corresponding to the attribute names of model objects:

# This list contains a Blog object.
>>> Blog.objects.filter(name__startswith='Beatles')
[Beatles Blog]

# This list contains a dictionary.
>>> Blog.objects.filter(name__startswith='Beatles').values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]

values() takes optional positional arguments, *fields, which specify field names to which the SELECT should be limited. If you specify the fields, each dictionary will contain only the field keys/values for the fields you specify. If you don’t specify the fields, each dictionary will contain a key and value for every field in the database table:

>>> Blog.objects.values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}],
>>> Blog.objects.values('id', 'name')
[{'id': 1, 'name': 'Beatles Blog'}]

This method is useful when you know you’re only going to need values from a small number of the available fields and you won’t need the functionality of a model instance object. It’s more efficient to select only the fields you need to use.

dates(field, kind, order)

Returns a special QuerySet that evaluates to a list of datetime.datetime objects representing all available dates of a particular kind within the contents of the QuerySet.

The field argument must be the name of a DateField or DateTimeField of your model. The kind argument must be either "year", "month", or "day". Each datetime.datetime object in the result list is “truncated” to the given type:

  • "year" returns a list of all distinct year values for the field.
  • "month" returns a list of all distinct year/month values for the field.
  • "day" returns a list of all distinct year/month/day values for the field.

order, which defaults to 'ASC', should be either 'ASC' or 'DESC'. This specifies how to order the results.

Here are a few examples:

>>> Entry.objects.dates('pub_date', 'year')
[datetime.datetime(2005, 1, 1)]

>>> Entry.objects.dates('pub_date', 'month')
[datetime.datetime(2005, 2, 1), datetime.datetime(2005, 3, 1)]

>>> Entry.objects.dates('pub_date', 'day')
[datetime.datetime(2005, 2, 20), datetime.datetime(2005, 3, 20)]

>>> Entry.objects.dates('pub_date', 'day', order='DESC')
[datetime.datetime(2005, 3, 20), datetime.datetime(2005, 2, 20)]

>>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
[datetime.datetime(2005, 3, 20)]

Sometimes, the Django query syntax by itself can’t easily express a complex WHERE clause. For these edge cases, Django provides the extra() QuerySet modifier — a hook for injecting specific clauses into the SQL generated by a QuerySet.

By definition, these extra lookups may not be portable to different database engines (because you’re explicitly writing SQL code) and violate the DRY principle, so you should avoid them if possible.

Specify one or more of params, select, where, or tables. None of the arguments is required, but you should use at least one of them.

The select argument lets you put extra fields in the SELECT clause. It should be a dictionary mapping attribute names to SQL clauses to use to calculate that attribute:

>>> Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})

As a result, each Entry object will have an extra attribute, is_recent, a Boolean representing whether the entry’s pub_date is greater than January 1, 2006.

The next example is more advanced; it does a subquery to give each resulting Blog object an entry_count attribute, an integer count of associated Entry objects:

>>> subq = 'SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id ='
>>> Blog.objects.extra(select={'entry_count': subq})

(In this particular case, we’re exploiting the fact that the query will already contain the blog_blog table in its FROM clause.)

You can define explicit SQL WHERE clauses — perhaps to perform nonexplicit joins — by using where. You can manually add tables to the SQL FROM clause by using tables.

where and tables both take a list of strings. All where parameters are ANDed to any other search criteria:

>>> Entry.objects.extra(where=['id IN (3, 4, 5, 20)'])

The select and where parameters described previously may use standard Python database string placeholders: '%s' to indicate parameters the database engine should automatically quote. The params argument is a list of any extra parameters to be substituted:

>>> Entry.objects.extra(where=['headline=%s'], params=['Lennon'])

Always use params instead of embedding values directly into select or where because params will ensure values are quoted correctly according to your particular database.

Here’s an example of the wrong way:

Entry.objects.extra(where=["headline='%s'" % name])

Here’s an example of the correct way:

Entry.objects.extra(where=['headline=%s'], params=[name])

QuerySet Methods That Do Not Return QuerySets

The following QuerySet methods evaluate the QuerySet and return something other than a QuerySet — a single object, value, and so forth.


Returns the object matching the given lookup parameters, which should be in the format described in the “Field Lookups” section. This raises AssertionError if more than one object was found.

get() raises a DoesNotExist exception if an object wasn’t found for the given parameters. The DoesNotExist exception is an attribute of the model class, for example:

>>> Entry.objects.get(id='foo') # raises Entry.DoesNotExist

The DoesNotExist exception inherits from django.core.exceptions.ObjectDoesNotExist, so you can target multiple DoesNotExist exceptions:

>>> from django.core.exceptions import ObjectDoesNotExist
>>> try:
...     e = Entry.objects.get(id=3)
...     b = Blog.objects.get(id=1)
... except ObjectDoesNotExist:
...     print "Either the entry or blog doesn't exist."

This is a convenience method for creating an object and saving it all in one step. It lets you compress two common steps:

>>> p = Person(first_name="Bruce", last_name="Springsteen")

into a single line:

>>> p = Person.objects.create(first_name="Bruce", last_name="Springsteen")

This is a convenience method for looking up an object and creating one if it doesn’t exist. It returns a tuple of (object, created), where object is the retrieved or created object and created is a Boolean specifying whether a new object was created.

This method is meant as a shortcut to boilerplate code and is mostly useful for data-import scripts, for example:

    obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
    obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))

This pattern gets quite unwieldy as the number of fields in a model increases. The previous example can be rewritten using get_or_create() like so:

obj, created = Person.objects.get_or_create(
    first_name = 'John',
    last_name  = 'Lennon',
    defaults   = {'birthday': date(1940, 10, 9)}

Any keyword arguments passed to get_or_create()except an optional one called defaults — will be used in a get() call. If an object is found, get_or_create() returns a tuple of that object and False. If an object is not found, get_or_create() will instantiate and save a new object, returning a tuple of the new object and True. The new object will be created according to this algorithm:

defaults = kwargs.pop('defaults', {})
params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
obj = self.model(**params)

In English, that means start with any non-'defaults' keyword argument that doesn’t contain a double underscore (which would indicate a nonexact lookup). Then add the contents of defaults, overriding any keys if necessary, and use the result as the keyword arguments to the model class.

If you have a field named defaults and want to use it as an exact lookup in get_or_create(), just use 'defaults__exact' like so:

    defaults__exact = 'bar',
    defaults={'defaults': 'baz'}


As mentioned earlier, get_or_create() is mostly useful in scripts that need to parse data and create new records if existing ones aren’t available. But if you need to use get_or_create() in a view, please make sure to use it only in POST requests unless you have a good reason not to. GET requests shouldn’t have any effect on data; use POST whenever a request to a page has a side effect on your data.


Returns an integer representing the number of objects in the database matching the QuerySet. count() never raises exceptions. Here’s an example:

# Returns the total number of entries in the database.
>>> Entry.objects.count()

# Returns the number of entries whose headline contains 'Lennon'
>>> Entry.objects.filter(headline__contains='Lennon').count()

count() performs a SELECT COUNT(*) behind the scenes, so you should always use count() rather than loading all of the records into Python objects and calling len() on the result.

Depending on which database you’re using (e.g., PostgreSQL or MySQL), count() may return a long integer instead of a normal Python integer. This is an underlying implementation quirk that shouldn’t pose any real-world problems.


Takes a list of primary key values and returns a dictionary mapping each primary key value to an instance of the object with the given ID, for example:

>>> Blog.objects.in_bulk([1])
{1: Beatles Blog}
>>> Blog.objects.in_bulk([1, 2])
{1: Beatles Blog, 2: Cheddar Talk}
>>> Blog.objects.in_bulk([])

IDs of objects that don’t exist are silently dropped from the result dictionary. If you pass in_bulk() an empty list, you’ll get an empty dictionary.


Returns the latest object in the table, by date, using the field_name provided as the date field. This example returns the latest Entry in the table, according to the pub_date field:

>>> Entry.objects.latest('pub_date')

If your model’s Meta specifies get_latest_by, you can leave off the field_name argument to latest(). Django will use the field specified in get_latest_by by default.

Like get(), latest() raises DoesNotExist if an object doesn’t exist with the given parameters.

Field Lookups

Field lookups are how you specify the meat of an SQL WHERE clause. They’re specified as keyword arguments to the QuerySet methods filter(), exclude(), and get().

Basic lookup keyword arguments take the form field__lookuptype=value (note the double underscore). For example:

>>> Entry.objects.filter(pub_date__lte='2006-01-01')

translates (roughly) into the following SQL:

SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01';

If you pass an invalid keyword argument, a lookup function will raise TypeError.

The supported lookup types follow.


Performs an exact match:

>>> Entry.objects.get(headline__exact="Man bites dog")

This matches any object with the exact headline “Man bites dog”.

If you don’t provide a lookup type — that is, if your keyword argument doesn’t contain a double underscore — the lookup type is assumed to be exact.

For example, the following two statements are equivalent:

>>> Blog.objects.get(id__exact=14) # Explicit form
>>> Blog.objects.get(id=14) # __exact is implied

This is for convenience, because exact lookups are the common case.


Performs a case-insensitive exact match:

>>> Blog.objects.get(name__iexact='beatles blog')

This will match 'Beatles Blog', 'beatles blog', 'BeAtLes BLoG', and so forth.


Performs a case-sensitive containment test:


This will match the headline 'Today Lennon honored' but not 'today lennon honored'.

SQLite doesn’t support case-sensitive LIKE statements; when using SQLite,``contains`` acts like icontains.

Escaping Percent Signs and Underscores in LIKE Statements

The field lookups that equate to LIKE SQL statements (iexact, contains, icontains, startswith, istartswith, endswith, and iendswith) will automatically escape the two special characters used in LIKE statements — the percent sign and the underscore. (In a LIKE statement, the percent sign signifies a multiple-character wildcard and the underscore signifies a single-character wildcard.)

This means things should work intuitively, so the abstraction doesn’t leak. For example, to retrieve all the entries that contain a percent sign, just use the percent sign as any other character:


Django takes care of the quoting for you. The resulting SQL will look something like this:

SELECT ... WHERE headline LIKE '%\%%';

The same goes for underscores. Both percentage signs and underscores are handled for you transparently.


Performs a case-insensitive containment test:

>>> Entry.objects.get(headline__icontains='Lennon')

Unlike contains, icontains will match 'today lennon honored'.

gt, gte, lt, and lte

These represent greater than, greater than or equal to, less than, and less than or equal to:

>>> Entry.objects.filter(id__gt=4)
>>> Entry.objects.filter(id__lt=15)
>>> Entry.objects.filter(id__gte=0)

These queries return any object with an ID greater than 4, an ID less than 15, and an ID greater than or equal to 1, respectively.

You’ll usually use these on numeric fields. Be careful with character fields since character order isn’t always what you’d expect (i.e., the string “4” sorts after the string “10”).


Filters where a value is on a given list:

Entry.objects.filter(id__in=[1, 3, 4])

This returns all objects with the ID 1, 3, or 4.


Performs a case-sensitive starts-with:

>>> Entry.objects.filter(headline__startswith='Will')

This will return the headlines “Will he run?” and “Willbur named judge”, but not “Who is Will?” or “will found in crypt”.


Performs a case-insensitive starts-with:

>>> Entry.objects.filter(headline__istartswith='will')

This will return the headlines “Will he run?”, “Willbur named judge”, and “will found in crypt”, but not “Who is Will?”

endswith and iendswith

Perform case-sensitive and case-insensitive ends-with:

>>> Entry.objects.filter(headline__endswith='cats')
>>> Entry.objects.filter(headline__iendswith='cats')


Performs an inclusive range check:

>>> start_date =, 1, 1)
>>> end_date =, 3, 31)
>>> Entry.objects.filter(pub_date__range=(start_date, end_date))

You can use range anywhere you can use BETWEEN in SQL — for dates, numbers, and even characters.

year, month, and day

For date/datetime fields, perform exact year, month, or day matches:

# Year lookup

# Month lookup -- takes integers
>>> Entry.objects.filter(pub_date__month=12)

# Day lookup
>>> Entry.objects.filter(pub_date__day=3)

# Combination: return all entries on Christmas of any year
>>> Entry.objects.filter(pub_date__month=12, pub_date_day=25)


Takes either True or False, which correspond to SQL queries of IS NULL and IS NOT NULL, respectively:

>>> Entry.objects.filter(pub_date__isnull=True)

__isnull=True vs. __exact=None

There is an important difference between __isnull=True and __exact=None. __exact=None will always return an empty result set, because SQL requires that no value is equal to NULL. __isnull determines if the field is currently holding the value of NULL without performing a comparison.

The pk Lookup Shortcut

For convenience, Django provides a pk lookup type, which stands for “primary_key”.

In the example Blog model, the primary key is the id field, so these three statements are equivalent:

>>> Blog.objects.get(id__exact=14) # Explicit form
>>> Blog.objects.get(id=14) # __exact is implied
>>> Blog.objects.get(pk=14) # pk implies id__exact

The use of pk isn’t limited to __exact queries — any query term can be combined with pk to perform a query on the primary key of a model:

# Get blogs entries  with id 1, 4, and 7
>>> Blog.objects.filter(pk__in=[1,4,7])

# Get all blog entries with id > 14
>>> Blog.objects.filter(pk__gt=14)

pk lookups also work across joins. For example, these three statements are equivalent:

>>> Entry.objects.filter(blog__id__exact=3) # Explicit form
>>> Entry.objects.filter(blog__id=3) # __exact is implied
>>> Entry.objects.filter(blog__pk=3) # __pk implies __id__exact

Complex Lookups with Q Objects

Keyword argument queries — in filter() and so on — are ANDed together. If you need to execute more complex queries (e.g., queries with OR statements), you can use Q objects.

A Q object (django.db.models.Q) is an object used to encapsulate a collection of keyword arguments. These keyword arguments are specified as in the “Field Lookups” section.

For example, this Q object encapsulates a single LIKE query:


Q objects can be combined using the & and | operators. When an operator is used on two Q objects, it yields a new Q object. For example, this statement yields a single Q object that represents the OR of two "question__startswith" queries:

Q(question__startswith='Who') | Q(question__startswith='What')

This is equivalent to the following SQL WHERE clause:

WHERE question LIKE 'Who%' OR question LIKE 'What%'

You can compose statements of arbitrary complexity by combining Q objects with the & and | operators. You can also use parenthetical grouping.

Each lookup function that takes keyword arguments (e.g., filter(), exclude(), get()) can also be passed one or more Q objects as positional (not-named) arguments. If you provide multiple Q object arguments to a lookup function, the arguments will be ANDed together, for example:

    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))

roughly translates into the following SQL:

SELECT * from polls WHERE question LIKE 'Who%'
    AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

Lookup functions can mix the use of Q objects and keyword arguments. All arguments provided to a lookup function (be they keyword arguments or Q objects) are ANDed together. However, if a Q object is provided, it must precede the definition of any keyword arguments. For example, the following:

    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),

would be a valid query, equivalent to the previous example, but this:

    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

would not be valid.

You can find some examples online at

Deleting Objects

The delete method, conveniently, is named delete(). This method immediately deletes the object and has no return value:


You can also delete objects in bulk. Every QuerySet has a delete() method, which deletes all members of that QuerySet. For example, this deletes all Entry objects with a pub_date year of 2005:


When Django deletes an object, it emulates the behavior of the SQL constraint ON DELETE CASCADE — in other words, any objects that had foreign keys pointing at the object to be deleted will be deleted along with it, for example:

b = Blog.objects.get(pk=1)
# This will delete the Blog and all of its Entry objects.

Note that delete() is the only QuerySet method that is not exposed on a Manager itself. This is a safety mechanism to prevent you from accidentally requesting Entry.objects.delete() and deleting all the entries. If you do want to delete all the objects, then you have to explicitly request a complete query set:


Extra Instance Methods

In addition to save() and delete(), a model object might get any or all of the following methods.


For every field that has choices set, the object will have a get_FOO_display() method, where FOO is the name of the field. This method returns the “human-readable” value of the field. For example, in the following model:

    ('M', 'Male'),
    ('F', 'Female'),
class Person(models.Model):
    name = models.CharField(max_length=20)
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES)

each Person instance will have a get_gender_display() method:

>>> p = Person(name='John', gender='M')
>>> p.gender
>>> p.get_gender_display()

get_next_by_FOO(**kwargs) and get_previous_by_FOO(**kwargs)

For every DateField and DateTimeField that does not have null=True, the object will have get_next_by_FOO() and get_previous_by_FOO() methods, where FOO is the name of the field. This returns the next and previous object with respect to the date field, raising the appropriate DoesNotExist exception when appropriate.

Both methods accept optional keyword arguments, which should be in the format described in the “Field Lookups” section.

Note that in the case of identical date values, these methods will use the ID as a fallback check. This guarantees that no records are skipped or duplicated. For a full example, see the lookup API samples at


For every FileField, the object will have a get_FOO_filename() method, where FOO is the name of the field. This returns the full filesystem path to the file, according to your MEDIA_ROOT setting.

Note that ImageField is technically a subclass of FileField, so every model with an ImageField will also get this method.


For every FileField, the object will have a get_FOO_url() method, where FOO is the name of the field. This returns the full URL to the file, according to your MEDIA_URL setting. If the value is blank, this method returns an empty string.


For every FileField, the object will have a get_FOO_size() method, where FOO is the name of the field. This returns the size of the file, in bytes. (Behind the scenes, it uses os.path.getsize.)

save_FOO_file(filename, raw_contents)

For every FileField, the object will have a save_FOO_file() method, where FOO is the name of the field. This saves the given file to the filesystem, using the given file name. If a file with the given file name already exists, Django adds an underscore to the end of the file name (but before the extension) until the file name is available.

get_FOO_height() and get_FOO_width()

For every ImageField, the object will have get_FOO_height() and get_FOO_width() methods, where FOO is the name of the field. This returns the height (or width) of the image, as an integer, in pixels.


As you develop views, you will discover a number of common idioms in the way you use the database API. Django encodes some of these idioms as shortcuts that can be used to simplify the process of writing views. These functions are in the django.shortcuts module.


One common idiom to use get() and raise Http404 if the object doesn’t exist. This idiom is captured by get_object_or_404(). This function takes a Django model as its first argument and an arbitrary number of keyword arguments, which it passes to the default manager’s get() function. It raises Http404 if the object doesn’t exist, for example:

# Get the Entry with a primary key of 3
e = get_object_or_404(Entry, pk=3)

When you provide a model to this shortcut function, the default manager is used to execute the underlying get() query. If you don’t want to use the default manager, or if you want to search a list of related objects, you can provide get_object_or_404() with a Manager object instead:

# Get the author of blog instance e with a name of 'Fred'
a = get_object_or_404(e.authors, name='Fred')

# Use a custom manager 'recent_entries' in the search for an
# entry with a primary key of 3
e = get_object_or_404(Entry.recent_entries, pk=3)


get_list_or_404 behaves the same way as get_object_or_404(), except that it uses filter() instead of get(). It raises Http404 if the list is empty.

Falling Back to Raw SQL

If you find yourself needing to write an SQL query that is too complex for Django’s database mapper to handle, you can fall back into raw SQL statement mode.

The preferred way to do this is by giving your model custom methods or custom manager methods that execute queries. Although there’s nothing in Django that requires database queries to live in the model layer, this approach keeps all your data access logic in one place, which is smart from a code organization standpoint. For instructions, see Appendix B..

Finally, it’s important to note that the Django database layer is merely an interface to your database. You can access your database via other tools, programming languages, or database frameworks — there’s nothing Django-specific about your database.

Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This work is licensed under the GNU Free Document License.
Hosting graciously provided by media temple
Comments X

      About this comment system

      This site is using a contextual comment system to help us gather targeted feedback about the book. Instead of commenting on an entire chapter, you can leave comments on any indivdual "block" in the chapter. A "block" with comments looks like this:

      A "block" is a paragraph, list item, code sample, or other small chunk of content. It'll get highlighted when you select it:

      To post a comment on a block, just click in the gutter next to the bit you want to comment on:

      As we edit the book, we'll review everyone's comments and roll them into a future version of the book. We'll mark reviewed comments with a little checkmark:

      Please make sure to leave a full name (and not a nickname or screenname) if you'd like your contributions acknowledged in print.

      Many, many thanks to Jack Slocum; the inspiration and much of the code for the comment system comes from Jack's blog, and this site couldn't have been built without his wonderful YAHOO.ext library. Thanks also to Yahoo for YUI itself.