Django documentation

Database API reference

This document is for Django's SVN release, which can be significantly different from previous releases. Get old docs here: 0.96, 0.95.

Once you’ve created your data models, Django automatically gives you a database-abstraction API that lets you create, retrieve, update and delete objects. This document explains that API.

Throughout this reference, we’ll refer to the following models, which comprise a weblog application:

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

    def __unicode__(self):
        return self.name

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

    def __unicode__(self):
        return self.name

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 __unicode__(self):
        return self.headline

Creating objects

To represent database-table data in Python objects, Django uses an intuitive system: A model class represents a database table, and an instance of that class represents a particular record in the database table.

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

You import the model class from wherever it lives on the Python path, as you may expect. (We point this out here because previous Django versions required funky model importing.)

Assuming models live in a file mysite/blog/models.py, here’s an example:

from mysite.blog.models import Blog
b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
b.save()

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 method.

Auto-incrementing primary keys

If a model has an AutoField — an auto-incrementing primary key — then that auto-incremented value will be calculated and saved as an attribute on your object the first time you call save().

Example:

b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.')
b2.id     # Returns None, because b doesn't have an ID yet.
b2.save()
b2.id     # 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.

(For convenience, each model has an AutoField named id by default unless you explicitly specify primary_key=True on a field. See the AutoField documentation.)

Explicitly specifying auto-primary-key values

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 auto-assignment of the ID.

Example:

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

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 above '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.')
b4.save()  # Overrides the previous blog with ID=3!

See How Django knows to UPDATE vs. INSERT, below, for the reason this happens.

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

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 not yet documented.)

  2. Pre-process 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 pre-processing — the field data is kept as-is. Pre-processing is only used on fields that have special behavior. For example, if your model has a DateField with auto_now=True, the pre-save phase will alter the data in the object to ensure that the date field contains the current date stamp. (Our documentation doesn’t yet include a list of all the fields with this “special behavior.”)

  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 pre-processed, 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. (These signals are not yet documented.)

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:

b5.name = 'New name'
b5.save()

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

The save() method has no return value.

Saving ForeignKey and ManyToManyField fields

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

cheese_blog = Blog.objects.get(name="Cheddar Talk")
entry.blog = cheese_blog
entry.save()

Updating a ManyToManyField works a little differently; use the add() method on the field to add a record to the relation:

joe = Author.objects.create(name="Joe")
entry.authors.add(joe)

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

How Django knows to UPDATE vs. INSERT

You may have noticed 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.

The one gotcha here is that 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. For more on this nuance, see Explicitly specifying auto-primary-key values above and Forcing an INSERT or UPDATE below.

Forcing an INSERT or UPDATE

New in Django development version

In some rare circumstances, it’s necesary to be able to force the save() method to perform an SQL INSERT and not fall back to doing an UPDATE. Or vice-versa: update, if possible, but not insert a new row. In these cases you can pass the force_insert=True or force_update=True parameters to the save() method. Passing both parameters is an error, since you cannot both insert and update at the same time.

It should be very rare that you’ll need to use these parameters. Django will almost always do the right thing and trying to override that will lead to errors that are difficult to track down. This feature is for advanced use only.

Retrieving objects

To retrieve objects from your database, you construct a QuerySet via a Manager on your model class.

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 ...>
b = Blog(name='Foo', tagline='Bar')
b.objects     # AttributeError: "Manager isn't accessible via Blog instances."

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

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.

Retrieving all 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.

Example:

all_entries = Entry.objects.all()

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

(If Entry.objects is a QuerySet, why can’t we just do Entry.objects? That’s because Entry.objects, the root QuerySet, is a special case that cannot be evaluated. The all() method returns a QuerySet that can be evaluated.)

Filtering objects

The root QuerySet provided by the Manager describes all objects in the database table. 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. The two most common ways to refine a QuerySet are:

filter(**kwargs)
Returns a new QuerySet containing objects that match the given lookup parameters.
exclude(**kwargs)
Returns a new QuerySet containing objects that do not match the given lookup parameters.

The lookup parameters (**kwargs in the above function definitions) should be in the format described in Field lookups below.

For example, to get a QuerySet of blog entries from the year 2006, use filter() like so:

Entry.objects.filter(pub_date__year=2006)

(Note we don’t have to add an all()Entry.objects.all().filter(...). That would still work, but you only need all() when you want all objects from the root QuerySet.)

Chaining filters

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

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

…takes the initial QuerySet of all entries in the database, adds a filter, then an exclusion, 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.

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.

Example:

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

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 criteria that excludes records whose pub_date is greater than now. The third is a subset of the first, with an additional criteria that selects only the records whose pub_date is greater than now. The initial QuerySet (q1) is unaffected by the refinement process.

QuerySets are lazy

QuerySets are lazy — the act of creating a QuerySet doesn’t involve any database activity. You can stack filters together all day long, and Django won’t actually run the query until the QuerySet is evaluated.

When QuerySets are evaluated

You can evaluate a QuerySet in the following ways:

  • Iteration. A QuerySet is iterable, and it executes its database query the first time you iterate over it. For example, this will print the headline of all entries in the database:

    for e in Entry.objects.all():
        print e.headline
    
  • Slicing. As explained in Limiting QuerySets below, 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.

  • repr(). 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.

  • len(). A QuerySet is evaluated when you call len() on it. This, as you might expect, returns the length of the result list.

    Note: Don’t use len() on QuerySets if all you want to do is determine the number of records in the set. It’s much more efficient to handle a count at the database level, using SQL’s SELECT COUNT(*), and Django provides a count() method for precisely this reason. See count() below.

  • list(). 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.

Pickling QuerySets

If you pickle a QuerySet, this will also force all the results to be loaded into memory prior to pickling. This is because pickling is usually used as a precursor to caching and when the cached QuerySet is reloaded, you want the results to already be present. This means that when you unpickle a QuerySet, it contains the results at the moment it was pickled, rather than the results that are currently in the database.

If you only want to pickle the necessary information to recreate the Queryset from the database at a later time, pickle the query attribute of the QuerySet. You can then recreate the original QuerySet (without any results loaded) using some code like this:

>>> import pickle
>>> query = pickle.loads(s)     # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query            # Restore the original 'query'.

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 5 objects (LIMIT 5):

Entry.objects.all()[:5]

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

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

You can also slice from the item ‘’N’’ to the end of the queryset. For example, to return everything from the sixth item onwards:

Entry.objects.all()[5:]

How this last example is implemented in SQL varies depending upon the database used, but it is supported in all cases.

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 10:

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:

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.

Combining QuerySets

If you have two QuerySet instances that act on the same model, you can combine them using & and | to get the items that are in both result sets or in either results set, respectively. For example:

Entry.objects.filter(pubdate__gte=date1) & \
        Entry.objects.filter(headline__startswith="What")

will combine the two queries into a single SQL query. Of course, in this case you could have achieved the same result using multiple filters on the same QuerySet, but sometimes the ability to combine individual QuerySet instance is useful.

Be careful, if you are using extra() to add custom handling to your QuerySet however. All the extra() components are merged and the result may or may not make sense. If you are using custom SQL fragments in your extra() calls, Django will not inspect these fragments to see if they need to be rewritten because of changes in the merged query. So test the effects carefully. Also realize that if you are combining two QuerySets with |, you cannot use extra(select=...) or extra(where=...) on both QuerySets. You can only use those calls on one or the other (Django will raise a ValueError if you try to use this incorrectly).

QuerySet 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.

filter(**kwargs)

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

The lookup parameters (**kwargs) should be in the format described in Field lookups below. Multiple parameters are joined via AND in the underlying SQL statement.

exclude(**kwargs)

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

The lookup parameters (**kwargs) should be in the format described in Field lookups below. Multiple parameters are joined via AND in the underlying SQL statement, and the whole thing is enclosed in a NOT().

This example excludes all entries whose pub_date is later than 2005-1-3 AND whose headline is “Hello”:

Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')

In SQL terms, that evaluates to:

SELECT ...
WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')

This example excludes all entries whose pub_date is later than 2005-1-3 OR whose headline is “Hello”:

Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello')

In SQL terms, that evaluates to:

SELECT ...
WHERE NOT pub_date > '2005-1-3'
AND NOT headline = 'Hello'

Note the second example is more restrictive.

order_by(*fields)

By default, results returned by a QuerySet are ordered by the ordering tuple given by the ordering option in the model’s Meta. You can override this on a per-QuerySet basis by using the order_by method.

Example:

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

The result above 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 implied. To order randomly, use "?", like so:

Entry.objects.order_by('?')

Note: order_by('?') queries may be expensive and slow, depending on the database backend you’re using.

To order by a field in a different model, use the same syntax as when you are querying across model relations. That is, the name of the field, followed by a double underscore (__), followed by the name of the field in the new model, and so on for as many models as you want to join. For example:

Entry.objects.order_by('blog__name', 'headline')

If you try to order by a field that is a relation to another model, Django will use the default ordering on the related model (or order by the related model’s primary key if there is no Meta.ordering specified. For example:

Entry.objects.order_by('blog')

…is identical to:

Entry.objects.order_by('blog__id')

…since the Blog model has no default ordering specified.

Be cautious when ordering by fields in related models if you are also using distinct(). See the note in the distinct() section for an explanation of how related model ordering can change the expected results.

It is permissible to specify a multi-valued field to order the results by (for example, a ManyToMany field). Normally this won’t be a sensible thing to do and it’s really an advanced usage feature. However, if you know that your queryset’s filtering or available data implies that there will only be one ordering piece of data for each of the main items you are selecting, the ordering may well be exactly what you want to do. Use ordering on multi-valued fields with care and make sure the results are what you expect.

New in Django development version: If you don’t want any ordering to be applied to a query, not even the default ordering, call order_by() with no parameters.

New in Django development version: The syntax for ordering across related models has changed. See the Django 0.96 documentation for the old behavior.

There’s no way to specify whether ordering should be case sensitive. With respect to case-sensitivity, Django will order results however your database backend normally orders them.

reverse()

New in Django development version

Use the reverse() method to reverse the order in which a queryset’s elements are returned. Calling reverse() a second time restores the ordering back to the normal direction.

To retrieve the ‘’last’’ five items in a queryset, you could do this:

my_queryset.reverse()[:5]

Note that this is not quite the same as slicing from the end of a sequence in Python. The above example will return the last item first, then the penultimate item and so on. If we had a Python sequence and looked at seq[:-5], we would see the fifth-last item first. Django doesn’t support that mode of access (slicing from the end), because it’s not possible to do it efficiently in SQL.

Also, note that reverse() should generally only be called on a QuerySet which has a defined ordering (e.g., when querying against a model which defines a default ordering, or when using order_by()). If no such ordering is defined for a given QuerySet, calling reverse() on it has no real effect (the ordering was undefined prior to calling reverse(), and will remain undefined afterward).

distinct()

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().

Note

Any fields used in an order_by() call are included in the SQL SELECT columns. This can sometimes lead to unexpected results when used in conjunction with distinct(). If you order by fields from a related model, those fields will be added to the selected columns and they may make otherwise duplicate rows appear to be distinct. Since the extra columns don’t appear in the returned results (they are only there to support ordering), it sometimes looks like non-distinct results are being returned.

Similarly, if you use a values() query to restrict the columns selected, the columns used in any order_by() (or default model ordering) will still be involved and may affect uniqueness of the results.

The moral here is that if you are using distinct() be careful about ordering by related models. Similarly, when using distinct() and values() together, be careful when ordering by fields not in the values() call.

values(*fields)

Returns a ValuesQuerySet — a 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 example compares the dictionaries of values() with the normal 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.

Example:

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

You can also retrieve values from across ForeignKey relations by using double underscores to separate the field names, just as when calling the filter() command. For example:

>>> Entry.objects.values('blog__name').distinct()
[{'name': 'Beatles Blog'}]

A couple of subtleties that are worth mentioning:

  • The values() method does not return anything for ManyToManyField attributes and will raise an error if you try to pass in this type of field to it.

  • If you have a field called foo that is a ForeignKey, the default values() call will return a dictionary key called foo_id, since this is the name of the hidden model attribute that stores the actual value (the foo attribute refers to the related model). When you are calling values() and passing in field names, you can pass in either foo or foo_id and you will get back the same thing (the dictionary key will match the field name you passed in).

    For example:

    >>> Entry.objects.values()
    [{'blog_id: 1, 'headline': u'First Entry', ...}, ...]
    
    >>> Entry.objects.values('blog')
    [{'blog': 1}, ...]
    
    >>> Entry.objects.values('blog_id')
    [{'blog_id': 1}, ...]
    
  • When using values() together with distinct(), be aware that ordering can affect the results. See the note in the distinct() section, above, for details.

New in Django development version: Previously, it was not possible to pass blog_id to values() in the above example, only blog.

A ValuesQuerySet 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.

Finally, note a ValuesQuerySet is a subclass of QuerySet, so it has all methods of QuerySet. You can call filter() on it, or order_by(), or whatever. Yes, that means these two calls are identical:

Blog.objects.values().order_by('id')
Blog.objects.order_by('id').values()

The people who made Django prefer to put all the SQL-affecting methods first, followed (optionally) by any output-affecting methods (such as values()), but it doesn’t really matter. This is your chance to really flaunt your individualism.

values_list(*fields)

New in Django development version

This is similar to values() except that instead of returning a list of dictionaries, it returns a list of tuples. Each tuple contains the value from the respective field passed into the values_list() call — so the first item is the first field, etc. For example:

>>> Entry.objects.values_list('id', 'headline')
[(1, u'First entry'), ...]

If you only pass in a single field, you can also pass in the flat parameter. If True, this will mean the returned results are single values, rather than one-tuples. An example should make the difference clearer:

>>> Entry.objects.values_list('id').order_by('id')
[(1,), (2,), (3,), ...]

>>> Entry.objects.values_list('id', flat=True).order_by('id')
[1, 2, 3, ...]

It is an error to pass in flat when there is more than one field.

If you don’t pass any values to values_list(), it will return all the fields in the model, in the order they were declared.

dates(field, kind, order='ASC')

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

field should be the name of a DateField or DateTimeField of your model.

kind should 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.

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)]

none()

New in Django development version

Returns an EmptyQuerySet — a QuerySet that always evaluates to an empty list. This can be used in cases where you know that you should return an empty result set and your caller is expecting a QuerySet object (instead of returning an empty list, for example.)

Examples:

>>> Entry.objects.none()
[]

all()

New in Django development version

Returns a ‘’copy’’ of the current QuerySet (or QuerySet subclass you pass in). This can be useful in some situations where you might want to pass in either a model manager or a QuerySet and do further filtering on the result. You can safely call all() on either object and then you’ll definitely have a QuerySet to work with.

extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)

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.

select

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.

Example:

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 Jan. 1, 2006.

Django inserts the given SQL snippet directly into the SELECT statement, so the resulting SQL of the above example would be:

SELECT blog_entry.*, (pub_date > '2006-01-01')
FROM blog_entry;

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:

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

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

The resulting SQL of the above example would be:

SELECT blog_blog.*, (SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id)
FROM blog_blog;

Note that the parenthesis required by most database engines around subqueries are not required in Django’s select clauses. Also note that some database backends, such as some MySQL versions, don’t support subqueries.

New in Django development version In some rare cases, you might wish to pass parameters to the SQL fragments in extra(select=...)`. For this purpose, use the select_params parameter. Since select_params is a sequence and the select attribute is a dictionary, some care is required so that the parameters are matched up correctly with the extra select pieces. In this situation, you should use a django.utils.datastructures.SortedDict for the select value, not just a normal Python dictionary.

This will work, for example:

Blog.objects.extra(
    select=SortedDict([('a', '%s'), ('b', '%s')]),
    select_params=('one', 'two'))

The only thing to be careful about when using select parameters in extra() is to avoid using the substring "%%s" (that’s two percent characters before the s) in the select strings. Django’s tracking of parameters looks for %s and an escaped % character like this isn’t detected. That will lead to incorrect results.

where / tables

You can define explicit SQL WHERE clauses — perhaps to perform non-explicit 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 “AND”ed to any other search criteria.

Example:

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

…translates (roughly) into the following SQL:

SELECT * FROM blog_entry WHERE id IN (3, 4, 5, 20);

Be careful when using the tables parameter if you’re specifying tables that are already used in the query. When you add extra tables via the tables parameter, Django assumes you want that table included an extra time, if it is already included. That creates a problem, since the table name will then be given an alias. If a table appears multiple times in an SQL statement, the second and subsequent occurrences must use aliases so the database can tell them apart. If you’re referring to the extra table you added in the extra where parameter this is going to cause errors.

Normally you’ll only be adding extra tables that don’t already appear in the query. However, if the case outlined above does occur, there are a few solutions. First, see if you can get by without including the extra table and use the one already in the query. If that isn’t possible, put your extra() call at the front of the queryset construction so that your table is the first use of that table. Finally, if all else fails, look at the query produced and rewrite your where addition to use the alias given to your extra table. The alias will be the same each time you construct the queryset in the same way, so you can rely upon the alias name to not change.

order_by

If you need to order the resulting queryset using some of the new fields or tables you have included via extra() use the order_by parameter to extra() and pass in a sequence of strings. These strings should either be model fields (as in the normal order_by() method on querysets), of the form table_name.column_name or an alias for a column that you specified in the select parameter to extra().

For example:

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

This would sort all the items for which is_recent is true to the front of the result set (True sorts before False in a descending ordering).

This shows, by the way, that you can make multiple calls to extra() and it will behave as you expect (adding new constraints each time).

params

The where parameter described above 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.

Example:

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

Always use params instead of embedding values directly into where because params will ensure values are quoted correctly according to your particular backend. (For example, quotes will be escaped correctly.)

Bad:

Entry.objects.extra(where=["headline='Lennon'"])

Good:

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

New in Django development version The select_params argument to extra() is new. Previously, you could attempt to pass parameters for select in the params argument, but it worked very unreliably.

QuerySet methods that do not return QuerySets

The following QuerySet methods evaluate the QuerySet and return something other than a QuerySet.

These methods do not use a cache (see Caching and QuerySets below). Rather, they query the database each time they’re called.

get(**kwargs)

Returns the object matching the given lookup parameters, which should be in the format described in Field lookups.

get() raises MultipleObjectsReturned if more than one object was found. The MultipleObjectsReturned exception is an attribute of the model class. For example, the following will raise MultipleObjectsReturned if there are more than one authors with the name of ‘John’:

Author.objects.get(name='John') # raises Author.MultipleObjectsReturned

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. 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. Example:

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."

create(**kwargs)

A convenience method for creating an object and saving it all in one step. Thus:

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

and:

p = Person(first_name="Bruce", last_name="Springsteen")
p.save()

are equivalent.

get_or_create(**kwargs)

A convenience method for looking up an object with the given kwargs, creating one if necessary.

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 is meant as a shortcut to boilerplatish code and is mostly useful for data-import scripts. For example:

try:
    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))
    obj.save()

This pattern gets quite unwieldy as the number of fields in a model goes up. The above 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])
params.update(defaults)
obj = self.model(**params)
obj.save()

In English, that means start with any non-'defaults' keyword argument that doesn’t contain a double underscore (which would indicate a non-exact 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:

Foo.objects.get_or_create(defaults__exact='bar', defaults={'defaults': 'baz'})

Finally, a word on using get_or_create() in Django views. 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. For more, see Safe methods in the HTTP spec.

count()

Returns an integer representing the number of objects in the database matching the QuerySet. count() never raises exceptions.

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 record into Python objects and calling len() on the result.

Depending on which database you’re using (e.g. PostgreSQL vs. 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.

in_bulk(id_list)

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.

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([])
{}

If you pass in_bulk() an empty list, you’ll get an empty dictionary.

iterator()

Evaluates the QuerySet (by performing the query) and returns an iterator over the results. A QuerySet typically reads all of its results and instantiates all of the corresponding objects the first time you access it; iterator() will instead read results and instantiate objects in discrete chunks, yielding them one at a time. For a QuerySet which returns a large number of objects, this often results in better performance and a significant reduction in memory use.

Note that using iterator() on a QuerySet which has already been evaluated will force it to evaluate again, repeating the query.

latest(field_name=None)

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.

Note latest() exists purely for convenience and readability.

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 lookups keyword arguments take the form field__lookuptype=value. (That’s a 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';

How this is possible

Python has the ability to define functions that accept arbitrary name-value arguments whose names and values are evaluated at runtime. For more information, see Keyword Arguments in the official Python tutorial.

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

The database API supports the following lookup types:

exact

Exact match. If the value provided for comparison is None, it will be interpreted as an SQL NULL (See isnull for more details).

Examples:

Entry.objects.get(id__exact=14)
Entry.objects.get(id__exact=None)

SQL equivalents:

SELECT ... WHERE id = 14;
SELECT ... WHERE id IS NULL;

New in Django development version: The semantics of id__exact=None have changed in the development version. Previously, it was (intentionally) converted to WHERE id = NULL at the SQL level, which would never match anything. It has now been changed to behave the same as id__isnull=True.

MySQL comparisons

In MySQL, whether or not exact comparisons are case-sensitive depends upon the collation setting of the table involved. The default is usually latin1_swedish_ci or utf8_swedish_ci, which results in case-insensitive comparisons. Change the collation to latin1_swedish_cs or utf8_bin for case sensitive comparisons.

For more details, refer to the MySQL manual section about character sets and collations.

iexact

Case-insensitive exact match.

Example:

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

SQL equivalent:

SELECT ... WHERE name ILIKE 'beatles blog';

Note this will match 'Beatles Blog', 'beatles blog', 'BeAtLes BLoG', etc.

contains

Case-sensitive containment test.

Example:

Entry.objects.get(headline__contains='Lennon')

SQL equivalent:

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

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

SQLite doesn’t support case-sensitive LIKE statements; contains acts like icontains for SQLite.

icontains

Case-insensitive containment test.

Example:

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

SQL equivalent:

SELECT ... WHERE headline ILIKE '%Lennon%';

gt

Greater than.

Example:

Entry.objects.filter(id__gt=4)

SQL equivalent:

SELECT ... WHERE id > 4;

gte

Greater than or equal to.

lt

Less than.

lte

Less than or equal to.

in

In a given list.

Example:

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

SQL equivalent:

SELECT ... WHERE id IN (1, 3, 4);

You can also use a queryset to dynamically evaluate the list of values instead of providing a list of literal values. The queryset must be reduced to a list of individual values using the values() method, and then converted into a query using the query attribute:

Entry.objects.filter(blog__in=Blog.objects.filter(name__contains='Cheddar').values('pk').query)

This queryset will be evaluated as subselect statement:

SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')

startswith

Case-sensitive starts-with.

Example:

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

SQL equivalent:

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

SQLite doesn’t support case-sensitive LIKE statements; startswith acts like istartswith for SQLite.

istartswith

Case-insensitive starts-with.

Example:

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

SQL equivalent:

SELECT ... WHERE headline ILIKE 'Will%';

endswith

Case-sensitive ends-with.

Example:

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

SQL equivalent:

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

SQLite doesn’t support case-sensitive LIKE statements; endswith acts like iendswith for SQLite.

iendswith

Case-insensitive ends-with.

Example:

Entry.objects.filter(headline__iendswith='will')

SQL equivalent:

SELECT ... WHERE headline ILIKE '%will'

range

Range test (inclusive).

Example:

start_date = datetime.date(2005, 1, 1)
end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date))

SQL equivalent:

SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';

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

year

For date/datetime fields, exact year match. Takes a four-digit year.

Example:

Entry.objects.filter(pub_date__year=2005)

SQL equivalent:

SELECT ... WHERE EXTRACT('year' FROM pub_date) = '2005';

(The exact SQL syntax varies for each database engine.)

month

For date/datetime fields, exact month match. Takes an integer 1 (January) through 12 (December).

Example:

Entry.objects.filter(pub_date__month=12)

SQL equivalent:

SELECT ... WHERE EXTRACT('month' FROM pub_date) = '12';

(The exact SQL syntax varies for each database engine.)

day

For date/datetime fields, exact day match.

Example:

Entry.objects.filter(pub_date__day=3)

SQL equivalent:

SELECT ... WHERE EXTRACT('day' FROM pub_date) = '3';

(The exact SQL syntax varies for each database engine.)

Note this will match any record with a pub_date on the third day of the month, such as January 3, July 3, etc.

isnull

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

Example:

Entry.objects.filter(pub_date__isnull=True)

SQL equivalent:

SELECT ... WHERE pub_date IS NULL;

regex

New in Django development version

Case-sensitive regular expression match.

The regular expression syntax is that of the database backend in use. In the case of SQLite, which doesn’t natively support regular-expression lookups, the syntax is that of Python’s re module.

Example:

Entry.objects.get(title__regex=r'^(An?|The) +')

SQL equivalents:

SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL

SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'c'); -- Oracle

SELECT ... WHERE title ~ '^(An?|The) +'; -- PostgreSQL

SELECT ... WHERE title REGEXP '^(An?|The) +'; -- SQLite

Using raw strings (e.g., r'foo' instead of 'foo') for passing in the regular expression syntax is recommended.

iregex

New in Django development version

Case-insensitive regular expression match.

Example:

Entry.objects.get(title__iregex=r'^(an?|the) +')

SQL equivalents:

SELECT ... WHERE title REGEXP '^(an?|the) +'; -- MySQL

SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'i'); -- Oracle

SELECT ... WHERE title ~* '^(an?|the) +'; -- PostgreSQL

SELECT ... WHERE title REGEXP '(?i)^(an?|the) +'; -- SQLite

Default lookups are exact

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.

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

Note

Because of this shortcut, you cannot have a field called pk that is not the primary key of the model. It will always be replaced by the name of the model’s primary key in queries.

Lookups that span relationships

Django offers a powerful and intuitive way to “follow” relationships in lookups, taking care of the SQL JOINs for you automatically, behind the scenes. To span a relationship, just use the field name of related fields across models, separated by double underscores, until you get to the field you want.

This example retrieves all Entry objects with a Blog whose name is 'Beatles Blog':

Entry.objects.filter(blog__name__exact='Beatles Blog')

This spanning can be as deep as you’d like.

It works backwards, too. To refer to a “reverse” relationship, just use the lowercase name of the model.

This example retrieves all Blog objects which have at least one Entry whose headline contains 'Lennon':

Blog.objects.filter(entry__headline__contains='Lennon')

If you are filtering across multiple relationships and one of the intermediate models doesn’t have a value that meets the filter condition, Django will treat it as if there is an empty (all values are NULL), but valid, object there. All this means is that no error will be raised. For example, in this filter:

Blog.objects.filter(entry__author__name='Lennon')

(if there was a related Author model), if there was no author associated with an entry, it would be treated as if there was also no name attached, rather than raising an error because of the missing author. Usually this is exactly what you want to have happen. The only case where it might be confusing is if you are using isnull. Thus:

Blog.objects.filter(entry__author__name__isnull=True)

will return Blog objects that have an empty name on the author and also those which have an empty author on the entry. If you don’t want those latter objects, you could write:

Blog.objetcs.filter(entry__author__isnull=False,
        entry__author__name__isnull=True)

Spanning multi-valued relationships

New in Django development version

When you are filtering an object based on a ManyToManyField or a reverse ForeignKeyField, there are two different sorts of filter you may be interested in. Consider the Blog/Entry relationship (Blog to Entry is a one-to-many relation). We might be interested in finding blogs that have an entry which has both “Lennon” in the headline and was published in 2008. Or we might want to find blogs that have an entry with “Lennon” in the headline as well as an entry that was published in 2008. Since there are multiple entries associated with a single Blog, both of these queries are possible and make sense in some situations.

The same type of situation arises with a ManyToManyField. For example, if an Entry has a ManyToManyField called tags, we might want to find entries linked to tags called “music” and “bands” or we might want an entry that contains a tag with a name of “music” and a status of “public”.

To handle both of these situations, Django has a consistent way of processing filter() and exclude() calls. Everything inside a single filter() call is applied simultaneously to filter out items matching all those requirements. Successive filter() calls further restrict the set of objects, but for multi-valued relations, they apply to any object linked to the primary model, not necessarily those objects that were selected by an earlier filter() call.

That may sound a bit confusing, so hopefully an example will clarify. To select all blogs that contains entries with “Lennon” in the headline and were published in 2008, we would write:

Blog.objects.filter(entry__headline__contains='Lennon',
        entry__pub_date__year=2008)

To select all blogs that contain an entry with “Lennon” in the headline as well as an entry that was published in 2008, we would write:

Blog.objects.filter(entry__headline__contains='Lennon').filter(
        entry__pub_date__year=2008)

In this second example, the first filter restricted the queryset to all those blogs linked to that particular type of entry. The second filter restricted the set of blogs further to those that are also linked to the second type of entry. The entries select by the second filter may or may not be the same as the entries in the first filter. We are filtering the Blog items with each filter statement, not the Entry items.

All of this behavior also applies to exclude(): all the conditions in a single exclude() statement apply to a single instance (if those conditions are talking about the same multi-valued relation). Conditions in subsequent filter() or exclude() calls that refer to the same relation may end up filtering on different linked objects.

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:

Entry.objects.filter(headline__contains='%')

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

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

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

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 QuerySets 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] # Re-use the cache from the evaluation.

Comparing objects

To compare two model instances, just use the standard Python comparison operator, the double equals sign: ==. Behind the scenes, that compares the primary key values of two models.

Using the Entry example above, the following two statements are equivalent:

some_entry == other_entry
some_entry.id == other_entry.id

If a model’s primary key isn’t called id, no problem. Comparisons will always use the primary key, whatever it’s called. For example, if a model’s primary key field is called name, these two statements are equivalent:

some_obj == other_obj
some_obj.name == other_obj.name

Complex lookups with Q objects

Keyword argument queries — in filter(), etc. — are “AND”ed together. If you need to execute more complex queries (for example, 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 “Field lookups” above.

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

Q(question__startswith='What')

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.

New in Django development version: Q objects can also be negated using the ~ operator, allowing for combined lookups that combine both a normal query and a negated (NOT) query:

Q(question__startswith='Who') | ~Q(pub_date__year=2005)

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 “AND”ed together. For example:

Poll.objects.get(
    Q(question__startswith='Who'),
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)

… roughly translates into the 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 “AND”ed together. However, if a Q object is provided, it must precede the definition of any keyword arguments. For example:

Poll.objects.get(
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
    question__startswith='Who')

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

# INVALID QUERY
Poll.objects.get(
    question__startswith='Who',
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

… would not be valid.

See the OR lookups examples page for more examples.