Making queries¶
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 how to use this API. Refer to the data model reference for full details of all the various model lookup options.
Throughout this guide (and in the reference), we’ll refer to the following models, which comprise a blog application:
from datetime import date
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
def __str__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField(default=date.today)
authors = models.ManyToManyField(Author)
number_of_comments = models.IntegerField(default=0)
number_of_pingbacks = models.IntegerField(default=0)
rating = models.IntegerField(default=5)
def __str__(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.
Assuming models live in a models.py
file inside a blog
Django app, here
is an example:
>>> from 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.
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()
.
Saving ForeignKey
and ManyToManyField
fields¶
Updating a ForeignKey
field works exactly the same
way as saving a normal field – assign an object of the right type to the field
in question. This example updates the blog
attribute of an Entry
instance entry
, assuming appropriate instances of Entry
and Blog
are already saved to the database (so we can retrieve them below):
>>> from blog.models import Blog, Entry
>>> entry = Entry.objects.get(pk=1)
>>> 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. This example adds the Author
instance
joe
to the entry
object:
>>> from blog.models import Author
>>> joe = Author.objects.create(name="Joe")
>>> entry.authors.add(joe)
To add multiple records to a ManyToManyField
in one
go, include multiple arguments in the call to
add()
, like this:
>>> john = Author.objects.create(name="John")
>>> paul = Author.objects.create(name="Paul")
>>> george = Author.objects.create(name="George")
>>> ringo = Author.objects.create(name="Ringo")
>>> entry.authors.add(john, paul, george, ringo)
Django will complain if you try to assign or add an object of the wrong type.
Retrieving objects¶
To retrieve objects from your database, 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. Filters narrow
down the query results based on the 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
Traceback:
...
AttributeError: "Manager isn't accessible via Blog instances."
Σημείωση
A Manager
is 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. For example, Blog.objects.all()
returns a
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
:
>>> all_entries = Entry.objects.all()
The all()
method returns a
QuerySet
of all the objects in the database.
Retrieving specific objects with filters¶
The QuerySet
returned by
all()
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)
With the default manager class, it is the same as:
Entry.objects.all().filter(pub_date__year=2006)
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.date.today()
... ).filter(pub_date__gte=datetime.date(2005, 1, 30))
This 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 30, 2005, and the current day.
Filtered QuerySet
s 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.date.today())
>>> q3 = q1.filter(pub_date__gte=datetime.date.today())
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 today or in the
future. The third is a subset of the first, with an additional criteria that
selects only the records whose pub_date
is today or in the future. The
initial QuerySet
(q1
) is unaffected by the
refinement process.
QuerySet
s are lazy¶
QuerySet
objects 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. Take a look at this example:
>>> q = Entry.objects.filter(headline__startswith="What")
>>> q = q.filter(pub_date__lte=datetime.date.today())
>>> q = q.exclude(body_text__icontains="food")
>>> print(q)
Though this looks like three database hits, in fact it hits the database only
once, at the last line (print(q)
). In general, the results of a
QuerySet
aren’t fetched from the database
until you «ask» for them. When you do, the
QuerySet
is evaluated by accessing the
database. For more details on exactly when evaluation takes place, see
When QuerySets are evaluated.
Retrieving a single object with get()
¶
filter()
will always give you a
QuerySet
, even if only a single object matches
the query - in this case, it will be a
QuerySet
containing a single element.
If you know there is only one object that matches your query, you can use the
get()
method on a
Manager
which returns the object directly:
>>> one_entry = Entry.objects.get(pk=1)
You can use any query expression with
get()
, just like with
filter()
- again, see Field lookups
below.
Note that there is a difference between using
get()
, and using
filter()
with a slice of [0]
. If
there are no results that match the query,
get()
will raise a DoesNotExist
exception. This exception is an attribute of the model class that the query is
being performed on - so in the code above, if there is no Entry
object with
a primary key of 1, Django will raise Entry.DoesNotExist
.
Similarly, Django will complain if more than one item matches the
get()
query. In this case, it will raise
MultipleObjectsReturned
, which again is an
attribute of the model class itself.
Other QuerySet
methods¶
Most of the time you’ll use all()
,
get()
,
filter()
and
exclude()
when you need to look up
objects from the database. However, that’s far from all there is; see the
QuerySet API Reference for a complete list of all the
various QuerySet
methods.
Limiting QuerySet
s¶
Use a subset of 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]
Negative indexing (i.e. Entry.objects.all()[-1]
) is not supported.
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: