Movatterモバイル変換


[0]ホーム

URL:


Skip to main content
Django

The web framework for perfectionists with deadlines.

Documentation

Making queries

Once you’ve created yourdata models, Djangoautomatically gives you a database-abstraction API that lets you create,retrieve, update and delete objects. This document explains how to use thisAPI. Refer to thedata model reference for fulldetails of all the various model lookup options.

Throughout this guide (and in the reference), we’ll refer to the followingmodels, which comprise a blog application:

fromdatetimeimportdatefromdjango.dbimportmodelsclassBlog(models.Model):name=models.CharField(max_length=100)tagline=models.TextField()def__str__(self):returnself.nameclassAuthor(models.Model):name=models.CharField(max_length=200)email=models.EmailField()def__str__(self):returnself.nameclassEntry(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):returnself.headline

Creating objects

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

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

Assuming models live in amodels.py file inside ablog Django app, hereis an example:

>>>fromblog.modelsimportBlog>>>b=Blog(name="Beatles Blog",tagline="All the latest Beatles news.")>>>b.save()

This performs anINSERT SQL statement behind the scenes. Django doesn’t hitthe database until you explicitly callsave().

Thesave() method has no return value.

See also

save() takes a number of advanced options notdescribed here. See the documentation forsave() for complete details.

To create and save an object in a single step, use thecreate() method.

Saving changes to objects

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

Given aBlog instanceb5 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 anUPDATE SQL statement behind the scenes. Django doesn’t hitthe database until you explicitly callsave().

SavingForeignKey andManyToManyField fields

Updating aForeignKey field works exactly the sameway as saving a normal field – assign an object of the right type to the fieldin question. This example updates theblog attribute of anEntryinstanceentry, assuming appropriate instances ofEntry andBlogare already saved to the database (so we can retrieve them below):

>>>fromblog.modelsimportBlog,Entry>>>entry=Entry.objects.get(pk=1)>>>cheese_blog=Blog.objects.get(name="Cheddar Talk")>>>entry.blog=cheese_blog>>>entry.save()

Updating aManyToManyField works a littledifferently – use theadd() method on the fieldto add a record to the relation. This example adds theAuthor instancejoe to theentry object:

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

To add multiple records to aManyToManyField in onego, include multiple arguments in the call toadd(), 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 aQuerySet via aManager on your model class.

AQuerySet represents a collection of objectsfrom your database. It can have zero, one or manyfilters. Filters narrowdown the query results based on the given parameters. In SQL terms, aQuerySet equates to aSELECT statement,and a filter is a limiting clause such asWHERE orLIMIT.

You get aQuerySet by using your model’sManager. Each model has at least oneManager, and it’s calledobjects by default. Access it directly via themodel class, like so:

>>>Blog.objects<django.db.models.manager.Manager object at ...>>>>b=Blog(name="Foo",tagline="Bar")>>>b.objectsTraceback:    ...AttributeError: "Manager isn't accessible via Blog instances."

Note

AManager is accessible only via model classes, rather than from modelinstances, to enforce a separation between “table-level” operations and“record-level” operations.

TheManager is the main source of querysets fora model. For example,Blog.objects.all() returns aQuerySet that contains allBlog objects inthe database.

Retrieving all objects

The simplest way to retrieve objects from a table is to get all of them. To dothis, use theall() method on aManager:

>>>all_entries=Entry.objects.all()

Theall() method returns aQuerySet of all the objects in the database.

Retrieving specific objects with filters

TheQuerySet returned byall() describes all objects in thedatabase table. Usually, though, you’ll need to select only a subset of thecomplete set of objects.

To create such a subset, you refine the initialQuerySet, adding filter conditions. The twomost common ways to refine aQuerySet are:

filter(**kwargs)

Returns a newQuerySet containing objectsthat match the given lookup parameters.

exclude(**kwargs)

Returns a newQuerySet containing objectsthat donot match the given lookup parameters.

The lookup parameters (**kwargs in the above function definitions) shouldbe in the format described inField lookups below.

For example, to get aQuerySet of blog entriesfrom the year 2006, usefilter() likeso:

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 aQuerySet is itself aQuerySet, so it’s possible to chainrefinements 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 initialQuerySet of all entriesin the database, adds a filter, then an exclusion, then another filter. Thefinal result is aQuerySet containing allentries with a headline that starts with “What”, that were published betweenJanuary 30, 2005, and the current day.

FilteredQuerySets are unique

Each time you refine aQuerySet, you get abrand-newQuerySet that is in no way bound tothe previousQuerySet. Each refinement createsa separate and distinctQuerySet that can bestored, 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 baseQuerySet containing all entries that contain aheadline starting with “What”. The second is a subset of the first, with anadditional criteria that excludes records whosepub_date is today or in thefuture. The third is a subset of the first, with an additional criteria thatselects only the records whosepub_date is today or in the future. TheinitialQuerySet (q1) is unaffected by therefinement process.

QuerySets are lazy

QuerySet objects are lazy – the act of creating aQuerySet doesn’t involve any databaseactivity. You can stack filters together all day long, and Django won’tactually run the query until theQuerySet isevaluated. 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 onlyonce, at the last line (print(q)). In general, the results of aQuerySet aren’t fetched from the databaseuntil you “ask” for them. When you do, theQuerySet isevaluated by accessing thedatabase. For more details on exactly when evaluation takes place, seeWhen QuerySets are evaluated.

Retrieving a single object withget()

filter() will always give you aQuerySet, even if only a single object matchesthe query - in this case, it will be aQuerySet containing a single element.

If you know there is only one object that matches your query, you can use theget() method on aManager which returns the object directly:

>>>one_entry=Entry.objects.get(pk=1)

You can use any query expression withget(), just like withfilter() - again, seeField lookupsbelow.

Note that there is a difference between usingget(), and usingfilter() with a slice of[0]. Ifthere are no results that match the query,get() will raise aDoesNotExistexception. This exception is an attribute of the model class that the query isbeing performed on - so in the code above, if there is noEntry object witha primary key of 1, Django will raiseEntry.DoesNotExist.

Similarly, Django will complain if more than one item matches theget() query. In this case, it will raiseMultipleObjectsReturned, which again is anattribute of the model class itself.

OtherQuerySet methods

Most of the time you’ll useall(),get(),filter() andexclude() when you need to look upobjects from the database. However, that’s far from all there is; see theQuerySet API Reference for a complete list of all thevariousQuerySet methods.

LimitingQuerySets

Use a subset of Python’s array-slicing syntax to limit yourQuerySet to a certain number of results. Thisis the equivalent of SQL’sLIMIT andOFFSET clauses.

For example, this returns the first 5 objects (LIMIT5):

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

This returns the sixth through tenth objects (OFFSET5LIMIT5):

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

Negative indexing (i.e.Entry.objects.all()[-1]) is not supported.

Generally, slicing aQuerySet returns a newQuerySet – it doesn’t evaluate the query. Anexception is if you use the “step” parameter of Python slice syntax. Forexample, this would actually execute the query in order to return a list ofeverysecond object of the first 10:

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

Further filtering or ordering of a sliced queryset is prohibited due to theambiguous nature of how that might work.

To retrieve asingle object rather than a list(e.g.SELECTfooFROMbarLIMIT1), use an index instead of a slice. Forexample, this returns the firstEntry in the database, after orderingentries 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 raiseIndexError while thesecond will raiseDoesNotExist if no objects match the given criteria. Seeget() for more details.

Field lookups

Field lookups are how you specify the meat of an SQLWHERE clause. They’respecified as keyword arguments to theQuerySetmethodsfilter(),exclude() andget().

Basic lookups keyword arguments take the formfield__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*FROMblog_entryWHEREpub_date<='2006-01-01';

How this is possible

Python has the ability to define functions that accept arbitrary name-valuearguments whose names and values are evaluated at runtime. For moreinformation, seeKeyword Arguments in the official Python tutorial.

The field specified in a lookup has to be the name of a model field. There’sone exception though, in case of aForeignKey youcan specify the field name suffixed with_id. In this case, the valueparameter is expected to contain the raw value of the foreign model’s primarykey. For example:

>>>Entry.objects.filter(blog_id=4)

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

The database API supports about two dozen lookup types; a complete referencecan be found in thefield lookup reference. To give youa taste of what’s available, here’s some of the more common lookups you’llprobably use:

exact

An “exact” match. For example:

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

Would generate SQL along these lines:

SELECT...WHEREheadline='Cat bites dog';

If you don’t provide a lookup type – that is, if your keyword argumentdoesn’t contain a double underscore – the lookup type is assumed to beexact.

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, becauseexact lookups are the common case.

iexact

A case-insensitive match. So, the query:

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

Would match aBlog titled"BeatlesBlog","beatlesblog", oreven"BeAtlESblOG".

contains

Case-sensitive containment test. For example:

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

Roughly translates to this SQL:

SELECT...WHEREheadlineLIKE'%Lennon%';

Note this will match the headline'TodayLennonhonored' but not'todaylennonhonored'.

There’s also a case-insensitive version,icontains.

startswith,endswith

Starts-with and ends-with search, respectively. There are alsocase-insensitive versions calledistartswith andiendswith.

Again, this only scratches the surface. A complete reference can be found inthefield lookup reference.

Lookups that span relationships

Django offers a powerful and intuitive way to “follow” relationships inlookups, taking care of the SQLJOINs for you automatically, behind thescenes. To span a relationship, use the field name of related fieldsacross models, separated by double underscores, until you get to the field youwant.

This example retrieves allEntry objects with aBlog whosenameis'BeatlesBlog':

>>>Entry.objects.filter(blog__name="Beatles Blog")

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

It works backwards, too. While itcanbecustomized, by default you refer to a “reverse”relationship in a lookup using the lowercase name of the model.

This example retrieves allBlog objects which have at least oneEntrywhoseheadline contains'Lennon':

>>>Blog.objects.filter(entry__headline__contains="Lennon")

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

Blog.objects.filter(entry__authors__name="Lennon")

(if there was a relatedAuthor model), if there was noauthorassociated with an entry, it would be treated as if there was also nonameattached, rather than raising an error because of the missingauthor.Usually this is exactly what you want to have happen. The only case where itmight be confusing is if you are usingisnull. Thus:

Blog.objects.filter(entry__authors__name__isnull=True)

will returnBlog objects that have an emptyname on theauthor andalso those which have an emptyauthor on theentry. If you don’t wantthose latter objects, you could write:

Blog.objects.filter(entry__authors__isnull=False,entry__authors__name__isnull=True)

Spanning multi-valued relationships

When spanning aManyToManyField or a reverseForeignKey (such as fromBlog toEntry),filtering on multiple attributes raises the question of whether to require eachattribute to coincide in the same related object. We might seek blogs that havean entry from 2008 with“Lennon” in its headline, or we might seek blogs thatmerely have any entry from 2008 as well as some newer or older entry with“Lennon” in its headline.

To select all blogs containing at least one entry from 2008 having“Lennon”in its headline (the same entry satisfying both conditions), we would write:

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

Otherwise, to perform a more permissive query selecting any blogs with merelysome entry with“Lennon” in its headline andsome entry from 2008, wewould write:

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

Suppose there is only one blog that has both entries containing“Lennon” andentries from 2008, but that none of the entries from 2008 contained“Lennon”.The first query would not return any blogs, but the second query would returnthat one blog. (This is because the entries selected by the second filter mayor may not be the same as the entries in the first filter. We are filtering theBlog items with each filter statement, not theEntry items.) In short,if each condition needs to match the same related object, then each should becontained in a singlefilter() call.

Note

As the second (more permissive) query chains multiple filters, it performsmultiple joins to the primary model, potentially yielding duplicates.

>>>fromdatetimeimportdate>>>beatles=Blog.objects.create(name="Beatles Blog")>>>pop=Blog.objects.create(name="Pop Music Blog")>>>Entry.objects.create(...blog=beatles,...headline="New Lennon Biography",...pub_date=date(2008,6,1),...)<Entry: New Lennon Biography>>>>Entry.objects.create(...blog=beatles,...headline="New Lennon Biography in Paperback",...pub_date=date(2009,6,1),...)<Entry: New Lennon Biography in Paperback>>>>Entry.objects.create(...blog=pop,...headline="Best Albums of 2008",...pub_date=date(2008,12,15),...)<Entry: Best Albums of 2008>>>>Entry.objects.create(...blog=pop,...headline="Lennon Would Have Loved Hip Hop",...pub_date=date(2020,4,1),...)<Entry: Lennon Would Have Loved Hip Hop>>>>Blog.objects.filter(...entry__headline__contains="Lennon",...entry__pub_date__year=2008,...)<QuerySet [<Blog: Beatles Blog>]>>>>Blog.objects.filter(...entry__headline__contains="Lennon",...).filter(...entry__pub_date__year=2008,...)<QuerySet [<Blog: Beatles Blog>, <Blog: Beatles Blog>, <Blog: Pop Music Blog]>

Note

The behavior offilter() for queriesthat span multi-value relationships, as described above, is not implementedequivalently forexclude(). Instead,the conditions in a singleexclude()call will not necessarily refer to the same item.

For example, the following query would exclude blogs that containbothentries with“Lennon” in the headlineand entries published in 2008:

Blog.objects.exclude(entry__headline__contains="Lennon",entry__pub_date__year=2008,)

However, unlike the behavior when usingfilter(), this will not limit blogsbased on entries that satisfy both conditions. In order to do that, i.e.to select all blogs that do not contain entries published with“Lennon”that were published in 2008, you need to make two queries:

Blog.objects.exclude(entry__in=Entry.objects.filter(headline__contains="Lennon",pub_date__year=2008,),)

Filters can reference fields on the model

In the examples given so far, we have constructed filters that comparethe value of a model field with a constant. But what if you want to comparethe value of a model field with another field on the same model?

Django providesFexpressions to allow suchcomparisons. Instances ofF() act as a reference to a model field within aquery. These references can then be used in query filters to compare the valuesof two different fields on the same model instance.

For example, to find a list of all blog entries that have had more commentsthan pingbacks, we construct anF() object to reference the pingback count,and use thatF() object in the query:

>>>fromdjango.db.modelsimportF>>>Entry.objects.filter(number_of_comments__gt=F("number_of_pingbacks"))

Django supports the use of addition, subtraction, multiplication, division,modulo, and power arithmetic withF() objects, both with constants and withotherF() objects. To find all the blog entries with more thantwice asmany comments as pingbacks, we modify the query:

>>>Entry.objects.filter(number_of_comments__gt=F("number_of_pingbacks")*2)

To find all the entries where the rating of the entry is less than thesum of the pingback count and comment count, we would issue thequery:

>>>Entry.objects.filter(rating__lt=F("number_of_comments")+F("number_of_pingbacks"))

You can also use the double underscore notation to span relationships inanF() object. AnF() object with a double underscore will introduceany joins needed to access the related object. For example, to retrieve allthe entries where the author’s name is the same as the blog name, we couldissue the query:

>>>Entry.objects.filter(authors__name=F("blog__name"))

For date and date/time fields, you can add or subtract atimedelta object. The following would return all entriesthat were modified more than 3 days after they were published:

>>>fromdatetimeimporttimedelta>>>Entry.objects.filter(mod_date__gt=F("pub_date")+timedelta(days=3))

TheF() objects support bitwise operations by.bitand(),.bitor(),.bitxor(),.bitrightshift(), and.bitleftshift(). For example:

>>>F("somefield").bitand(16)

Oracle

Oracle doesn’t support bitwise XOR operation.

Expressions can reference transforms

Django supports using transforms in expressions.

For example, to find allEntry objects published in the same year as theywere last modified:

>>>fromdjango.db.modelsimportF>>>Entry.objects.filter(pub_date__year=F("mod_date__year"))

To find the earliest year an entry was published, we can issue the query:

>>>fromdjango.db.modelsimportMin>>>Entry.objects.aggregate(first_published_year=Min("pub_date__year"))

This example finds the value of the highest rated entry and the total numberof comments on all entries for each year:

>>>fromdjango.db.modelsimportOuterRef,Subquery,Sum>>>Entry.objects.values("pub_date__year").annotate(...top_rating=Subquery(...Entry.objects.filter(...pub_date__year=OuterRef("pub_date__year"),...)....order_by("-rating")....values("rating")[:1]...),...total_comments=Sum("number_of_comments"),...)

Thepk lookup shortcut

For convenience, Django provides apk lookup shortcut, which stands for“primary key”.

In the exampleBlog model, the primary key is theid field, so thesethree 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 ofpk isn’t limited to__exact queries – any query termcan be combined withpk 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 areequivalent:

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

Escaping percent signs and underscores inLIKE statements

The field lookups that equate toLIKE SQL statements (iexact,contains,icontains,startswith,istartswith,endswithandiendswith) will automatically escape the two special characters used inLIKE statements – the percent sign and the underscore. (In aLIKEstatement, the percent sign signifies a multiple-character wildcard and theunderscore 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, use thepercent sign as any other character:

>>>Entry.objects.filter(headline__contains="%")

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

SELECT...WHEREheadlineLIKE'%\%%';

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

Caching andQuerySets

EachQuerySet contains a cache to minimizedatabase access. Understanding how it works will allow you to write the mostefficient code.

In a newly createdQuerySet, the cache isempty. The first time aQuerySet is evaluated– and, hence, a database query happens – Django saves the query results intheQuerySet’s cache and returns the resultsthat have been explicitly requested (e.g., the next element, if theQuerySet is being iterated over). Subsequentevaluations of theQuerySet reuse the cachedresults.

Keep this caching behavior in mind, because it may bite you if you don’t useyourQuerySets correctly. For example, thefollowing will create twoQuerySets, evaluatethem, and throw them away:

>>>print([e.headlineforeinEntry.objects.all()])>>>print([e.pub_dateforeinEntry.objects.all()])

That means the same database query will be executed twice, effectively doublingyour database load. Also, there’s a possibility the two lists may not includethe same database records, because anEntry may have been added or deletedin the split second between the two requests.

To avoid this problem, save theQuerySet andreuse it:

>>>queryset=Entry.objects.all()>>>print([p.headlineforpinqueryset])# Evaluate the query set.>>>print([p.pub_dateforpinqueryset])# Reuse the cache from the evaluation.

WhenQuerySets are not cached

Querysets do not always cache their results. When evaluating onlypart ofthe queryset, the cache is checked, but if it is not populated then the itemsreturned by the subsequent query are not cached. Specifically, this means thatlimiting the queryset using an array slice or anindex will not populate the cache.

For example, repeatedly getting a certain index in a queryset object will querythe database each time:

>>>queryset=Entry.objects.all()>>>print(queryset[5])# Queries the database>>>print(queryset[5])# Queries the database again

However, if the entire queryset has already been evaluated, the cache will bechecked instead:

>>>queryset=Entry.objects.all()>>>[entryforentryinqueryset]# Queries the database>>>print(queryset[5])# Uses cache>>>print(queryset[5])# Uses cache

Here are some examples of other actions that will result in the entire querysetbeing evaluated and therefore populate the cache:

>>>[entryforentryinqueryset]>>>bool(queryset)>>>entryinqueryset>>>list(queryset)

Note

Simply printing the queryset will not populate the cache. This is becausethe call to__repr__() only returns a slice of the entire queryset.

Asynchronous queries

If you are writing asynchronous views or code, you cannot use the ORM forqueries in quite the way we have described above, as you cannot callblockingsynchronous code from asynchronous code - it will block up the event loop(or, more likely, Django will notice and raise aSynchronousOnlyOperationto stop that from happening).

Fortunately, you can do many queries using Django’s asynchronous query APIs.Every method that might block - such asget() ordelete() - has anasynchronous variant (aget() oradelete()), and when you iterate overresults, you can use asynchronous iteration (asyncfor) instead.

Query iteration

The default way of iterating over a query - withfor - will result in ablocking database query behind the scenes as Django loads the results atiteration time. To fix this, you can swap toasyncfor:

asyncforentryinAuthors.objects.filter(name__startswith="A"):...

Be aware that you also can’t do other things that might iterate over thequeryset, such as wrappinglist() around it to force its evaluation (youcan useasyncfor in a comprehension, if you want it).

BecauseQuerySet methods likefilter() andexclude() do notactually run the query - they set up the queryset to run when it’s iteratedover - you can use those freely in asynchronous code. For a guide to whichmethods can keep being used like this, and which have asynchronous versions,read the next section.

QuerySet and manager methods

Some methods on managers and querysets - likeget() andfirst() - forceexecution of the queryset and are blocking. Some, likefilter() andexclude(), don’t force execution and so are safe to run from asynchronouscode. But how are you supposed to tell the difference?

While you could poke around and see if there is ana-prefixed version ofthe method (for example, we haveaget() but notafilter()), there is amore logical way - look up what kind of method it is in theQuerySet reference.

In there, you’ll find the methods on QuerySets grouped into two sections:

  • Methods that return new querysets: These are the non-blocking ones,and don’t have asynchronous versions. You’re free to use these in anysituation, though read the notes ondefer() andonly() before you usethem.

  • Methods that do not return querysets: These are the blocking ones, andhave asynchronous versions - the asynchronous name for each is noted in itsdocumentation, though our standard pattern is to add ana prefix.

Using this distinction, you can work out when you need to use asynchronousversions, and when you don’t. For example, here’s a valid asynchronous query:

user=awaitUser.objects.filter(username=my_input).afirst()

filter() returns a queryset, and so it’s fine to keep chaining it inside anasynchronous environment, whereasfirst() evaluates and returns a modelinstance - thus, we change toafirst(), and useawait at the front ofthe whole expression in order to call it in an asynchronous-friendly way.

Note

If you forget to put theawait part in, you may see errors like“coroutine object has no attribute x” or“<coroutine …>” strings inplace of your model instances. If you ever see these, you are missing anawait somewhere to turn that coroutine into a real value.

Transactions

Transactions arenot currently supported with asynchronous queries andupdates. You will find that trying to use one raisesSynchronousOnlyOperation.

If you wish to use a transaction, we suggest you write your ORM code inside aseparate, synchronous function and then call that usingsync_to_async - seeAsynchronous support for more.

QueryingJSONField

Lookups implementation is different inJSONField,mainly due to the existence of key transformations. To demonstrate, we will usethe following example model:

fromdjango.dbimportmodelsclassDog(models.Model):name=models.CharField(max_length=200)data=models.JSONField(null=True)def__str__(self):returnself.name

Storing and querying forNone

As with other fields, storingNone as the field’s value will store it asSQLNULL. While not recommended, it is possible to store JSON scalarnull instead of SQLNULL by usingValue(None,JSONField()).

Whichever of the values is stored, when retrieved from the database, the Pythonrepresentation of the JSON scalarnull is the same as SQLNULL, i.e.None. Therefore, it can be hard to distinguish between them.

This only applies toNone as the top-level value of the field. IfNoneis inside alist ordict, it will always be interpretedas JSONnull.

When querying,None value will always be interpreted as JSONnull. Toquery for SQLNULL, useisnull:

>>>Dog.objects.create(name="Max",data=None)# SQL NULL.<Dog: Max>>>>Dog.objects.create(name="Archie",data=Value(None,JSONField()))# JSON null.<Dog: Archie>>>>Dog.objects.filter(data=None)<QuerySet [<Dog: Archie>]>>>>Dog.objects.filter(data=Value(None,JSONField()))<QuerySet [<Dog: Archie>]>>>>Dog.objects.filter(data__isnull=True)<QuerySet [<Dog: Max>]>>>>Dog.objects.filter(data__isnull=False)<QuerySet [<Dog: Archie>]>

Unless you are sure you wish to work with SQLNULL values, consider settingnull=False and providing a suitable default for empty values, such asdefault=dict.

Note

Storing JSON scalarnull does not violatenull=False.

Key, index, and path transforms

To query based on a given dictionary key, use that key as the lookup name:

>>>Dog.objects.create(...name="Rufus",...data={..."breed":"labrador",..."owner":{..."name":"Bob",..."other_pets":[...{..."name":"Fishy",...}...],...},...},...)<Dog: Rufus>>>>Dog.objects.create(name="Meg",data={"breed":"collie","owner":None})<Dog: Meg>>>>Dog.objects.filter(data__breed="collie")<QuerySet [<Dog: Meg>]>

Multiple keys can be chained together to form a path lookup:

>>>Dog.objects.filter(data__owner__name="Bob")<QuerySet [<Dog: Rufus>]>

If the key is an integer, it will be interpreted as an index transform in anarray:

>>>Dog.objects.filter(data__owner__other_pets__0__name="Fishy")<QuerySet [<Dog: Rufus>]>

If the key is a negative integer, it cannot be used in a filter keyworddirectly, but you can still use dictionary unpacking to use it in a query:

>>>Dog.objects.filter(**{"data__owner__other_pets__-1__name":"Fishy"})<QuerySet [<Dog: Rufus>]>

MySQL, MariaDB, and Oracle

Negative JSON array indices are not supported.

Changed in Django 6.0:

SQLite support for negative JSON array indices was added.

If the key you wish to query by clashes with the name of another lookup, usethecontains lookup instead.

To query for missing keys, use theisnull lookup:

>>>Dog.objects.create(name="Shep",data={"breed":"collie"})<Dog: Shep>>>>Dog.objects.filter(data__owner__isnull=True)<QuerySet [<Dog: Shep>]>

Note

The lookup examples given above implicitly use theexact lookup.Key, index, and path transforms can also be chained with:icontains,endswith,iendswith,iexact,regex,iregex,startswith,istartswith,lt,lte,gt, andgte, as well as withContainment and key lookups.

KT() expressions

classKT(lookup)

Represents the text value of a key, index, or path transform ofJSONField. You can use the double underscorenotation inlookup to chain dictionary key and index transforms.

For example:

>>>fromdjango.db.models.fields.jsonimportKT>>>Dog.objects.create(...name="Shep",...data={..."owner":{"name":"Bob"},..."breed":["collie","lhasa apso"],...},...)<Dog: Shep>>>>Dog.objects.annotate(...first_breed=KT("data__breed__1"),owner_name=KT("data__owner__name")...).filter(first_breed__startswith="lhasa",owner_name="Bob")<QuerySet [<Dog: Shep>]>

Note

Due to the way in which key-path queries work,exclude() andfilter() are not guaranteed toproduce exhaustive sets. If you want to include objects that do not havethe path, add theisnull lookup.

Warning

Since any string could be a key in a JSON object, any lookup other thanthose listed below will be interpreted as a key lookup. No errors areraised. Be extra careful for typing mistakes, and always check your querieswork as you intend.

MariaDB and Oracle users

Usingorder_by() on key, index, orpath transforms will sort the objects using the string representation ofthe values. This is because MariaDB and Oracle Database do not provide afunction that converts JSON values into their equivalent SQL values.

Oracle users

On Oracle Database, usingNone as the lookup value in anexclude() query will return objectsthat do not havenull as the value at the given path, including objectsthat do not have the path. On other database backends, the query willreturn objects that have the path and the value is notnull.

PostgreSQL users

On PostgreSQL, if only one key or index is used, the SQL operator-> isused. If multiple operators are used then the#> operator is used.

SQLite users

On SQLite,"true","false", and"null" string values willalways be interpreted asTrue,False, and JSONnullrespectively.

Containment and key lookups

contains

Thecontains lookup is overridden onJSONField. The returnedobjects are those where the givendict of key-value pairs are allcontained in the top-level of the field. For example:

>>>Dog.objects.create(name="Rufus",data={"breed":"labrador","owner":"Bob"})<Dog: Rufus>>>>Dog.objects.create(name="Meg",data={"breed":"collie","owner":"Bob"})<Dog: Meg>>>>Dog.objects.create(name="Fred",data={})<Dog: Fred>>>>Dog.objects.create(...name="Merry",data={"breed":"pekingese","tricks":["fetch","dance"]}...)>>>Dog.objects.filter(data__contains={"owner":"Bob"})<QuerySet [<Dog: Rufus>, <Dog: Meg>]>>>>Dog.objects.filter(data__contains={"breed":"collie"})<QuerySet [<Dog: Meg>]>>>>Dog.objects.filter(data__contains={"tricks":["dance"]})<QuerySet [<Dog: Merry>]>

Oracle and SQLite

contains is not supported on Oracle and SQLite.

contained_by

This is the inverse of thecontains lookup - theobjects returned will be those where the key-value pairs on the object are asubset of those in the value passed. For example:

>>>Dog.objects.create(name="Rufus",data={"breed":"labrador","owner":"Bob"})<Dog: Rufus>>>>Dog.objects.create(name="Meg",data={"breed":"collie","owner":"Bob"})<Dog: Meg>>>>Dog.objects.create(name="Fred",data={})<Dog: Fred>>>>Dog.objects.create(...name="Merry",data={"breed":"pekingese","tricks":["fetch","dance"]}...)>>>Dog.objects.filter(data__contained_by={"breed":"collie","owner":"Bob"})<QuerySet [<Dog: Meg>, <Dog: Fred>]>>>>Dog.objects.filter(data__contained_by={"breed":"collie"})<QuerySet [<Dog: Fred>]>>>>Dog.objects.filter(...data__contained_by={"breed":"pekingese","tricks":["dance","fetch","hug"]}...)<QuerySet [<Dog: Merry>, <Dog: Fred>]>

Oracle and SQLite

contained_by is not supported on Oracle and SQLite.

has_key

Returns objects where the given key is in the top-level of the data. Forexample:

>>>Dog.objects.create(name="Rufus",data={"breed":"labrador"})<Dog: Rufus>>>>Dog.objects.create(name="Meg",data={"breed":"collie","owner":"Bob"})<Dog: Meg>>>>Dog.objects.filter(data__has_key="owner")<QuerySet [<Dog: Meg>]>

has_keys

Returns objects where all of the given keys are in the top-level of the data.For example:

>>>Dog.objects.create(name="Rufus",data={"breed":"labrador"})<Dog: Rufus>>>>Dog.objects.create(name="Meg",data={"breed":"collie","owner":"Bob"})<Dog: Meg>>>>Dog.objects.filter(data__has_keys=["breed","owner"])<QuerySet [<Dog: Meg>]>

has_any_keys

Returns objects where any of the given keys are in the top-level of the data.For example:

>>>Dog.objects.create(name="Rufus",data={"breed":"labrador"})<Dog: Rufus>>>>Dog.objects.create(name="Meg",data={"owner":"Bob"})<Dog: Meg>>>>Dog.objects.filter(data__has_any_keys=["owner","breed"])<QuerySet [<Dog: Rufus>, <Dog: Meg>]>

Complex lookups withQ objects

Keyword argument queries – infilter(),etc. – are “AND”ed together. If you need to execute more complex queries (forexample, queries withOR statements), you can useQobjects.

AQobject (django.db.models.Q) is an objectused to encapsulate a collection of keyword arguments. These keyword argumentsare specified as in “Field lookups” above.

For example, thisQ object encapsulates a singleLIKE query:

fromdjango.db.modelsimportQQ(question__startswith="What")

Q objects can be combined using the&,|, and^ operators. Whenan operator is used on twoQ objects, it yields a newQ object.

For example, this statement yields a singleQ object that represents the“OR” of two"question__startswith" queries:

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

This is equivalent to the following SQLWHERE clause:

WHEREquestionLIKE'Who%'ORquestionLIKE'What%'

You can compose statements of arbitrary complexity by combiningQ objectswith the&,|, and^ operators and use parenthetical grouping.Also,Q objects can be negated using the~ operator, allowing forcombined 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 moreQ objects as positional (not-named) arguments. If you provide multipleQ object arguments to a lookup function, the arguments will be “AND”edtogether. 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*frompollsWHEREquestionLIKE'Who%'AND(pub_date='2005-05-02'ORpub_date='2005-05-06')

Lookup functions can mix the use ofQ objects and keyword arguments. Allarguments provided to a lookup function (be they keyword arguments orQobjects) are “AND”ed together. However, if aQ object is provided, it mustprecede 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 QUERYPoll.objects.get(question__startswith="Who",Q(pub_date=date(2005,5,2))|Q(pub_date=date(2005,5,6)),)

… would not be valid.

See also

TheOR lookups examples in Django’sunit tests show some possible uses ofQ.

Comparing objects

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

Using theEntry 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 calledid, no problem. Comparisons willalways use the primary key, whatever it’s called. For example, if a model’sprimary key field is calledname, these two statements are equivalent:

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

Deleting objects

The delete method, conveniently, is nameddelete(). This method immediately deletes theobject and returns the number of objects deleted and a dictionary withthe number of deletions per object type. Example:

>>>e.delete()(1, {'blog.Entry': 1})

You can also delete objects in bulk. EveryQuerySet has adelete() method, which deletes allmembers of thatQuerySet.

For example, this deletes allEntry objects with apub_date year of2005:

>>>Entry.objects.filter(pub_date__year=2005).delete()(5, {'webapp.Entry': 5})

Keep in mind that this will, whenever possible, be executed purely in SQL, andso thedelete() methods of individual object instances will not necessarilybe called during the process. If you’ve provided a customdelete() methodon a model class and want to ensure that it is called, you will need to“manually” delete instances of that model (e.g., by iterating over aQuerySet and callingdelete() on eachobject individually) rather than using the bulkdelete() method of aQuerySet.

When Django deletes an object, by default it emulates the behavior of the SQLconstraintONDELETECASCADE – in other words, any objects which hadforeign keys pointing at the object to be deleted will be deleted along withit. For example:

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

This cascade behavior is customizable via theon_delete argument to theForeignKey.

Note thatdelete() is the onlyQuerySet method that is not exposed on aManager itself. This is a safety mechanism toprevent you from accidentally requestingEntry.objects.delete(), anddeletingall the entries. If youdo want to delete all the objects, thenyou have to explicitly request a complete query set:

Entry.objects.all().delete()

Copying model instances

Although there is no built-in method for copying model instances, it ispossible to easily create new instance with all fields’ values copied. In thesimplest case, you can setpk toNone and_state.adding toTrue. Using ourblog example:

blog=Blog(name="My blog",tagline="Blogging is easy")blog.save()# blog.pk == 1blog.pk=Noneblog._state.adding=Trueblog.save()# blog.pk == 2

Things get more complicated if you use inheritance. Consider a subclass ofBlog:

classThemeBlog(Blog):theme=models.CharField(max_length=200)django_blog=ThemeBlog(name="Django",tagline="Django is easy",theme="python")django_blog.save()# django_blog.pk == 3

Due to how inheritance works, you have to set bothpk andid toNone, and_state.adding toTrue:

django_blog.pk=Nonedjango_blog.id=Nonedjango_blog._state.adding=Truedjango_blog.save()# django_blog.pk == 4

This process doesn’t copy relations that aren’t part of the model’s databasetable. For example,Entry has aManyToManyField toAuthor. Afterduplicating an entry, you must set the many-to-many relations for the newentry:

entry=Entry.objects.all()[0]# some previous entryold_authors=entry.authors.all()entry.pk=Noneentry._state.adding=Trueentry.save()entry.authors.set(old_authors)

For aOneToOneField, you must duplicate the related object and assign itto the new object’s field to avoid violating the one-to-one unique constraint.For example, assumingentry is already duplicated as above:

detail=EntryDetail.objects.all()[0]detail.pk=Nonedetail._state.adding=Truedetail.entry=entrydetail.save()

Note that it is not possible to copy instances of models with deferred fieldsusing this pattern unless values are assigned to them:

>>>blog=Blog.objects.defer("name")[0]>>>blog.pk=None>>>blog._state.adding=True>>>blog.save()Traceback (most recent call last):...AttributeError:Cannot retrieve deferred field 'name' from an unsaved model.>>>blog.name="Another Blog">>>blog.save()

Updating multiple objects at once

Sometimes you want to set a field to a particular value for all the objects inaQuerySet. You can do this with theupdate() method. For example:

# Update all the headlines with pub_date in 2007.Entry.objects.filter(pub_date__year=2007).update(headline="Everything is the same")

You can only set non-relation fields andForeignKeyfields using this method. To update a non-relation field, provide the new valueas a constant. To updateForeignKey fields, set thenew value to be the new model instance you want to point to. For example:

>>>b=Blog.objects.get(pk=1)# Change every Entry so that it belongs to this Blog.>>>Entry.objects.update(blog=b)

Theupdate() method is applied instantly and returns the number of rowsmatched by the query (which may not be equal to the number of rows updated ifsome rows already have the new value). The only restriction on theQuerySet being updated is that it can onlyaccess one database table: the model’s main table. You can filter based onrelated fields, but you can only update columns in the model’s maintable. Example:

>>>b=Blog.objects.get(pk=1)# Update all the headlines belonging to this Blog.>>>Entry.objects.filter(blog=b).update(headline="Everything is the same")

Be aware that theupdate() method is converted directly to an SQLstatement. It is a bulk operation for direct updates. It doesn’t run anysave() methods on your models, or emit thepre_save orpost_save signals (which are a consequence of callingsave()), or honor theauto_now field option.If you want to save every item in aQuerySetand make sure that thesave() method is called oneach instance, you don’t need any special function to handle that. Loop overthem and callsave():

foriteminmy_queryset:item.save()

Calls to update can also useFexpressions toupdate one field based on the value of another field in the model. This isespecially useful for incrementing counters based upon their current value. Forexample, to increment the pingback count for every entry in the blog:

>>>Entry.objects.update(number_of_pingbacks=F("number_of_pingbacks")+1)

However, unlikeF() objects in filter and exclude clauses, you can’tintroduce joins when you useF() objects in an update – you can onlyreference fields local to the model being updated. If you attempt to introducea join with anF() object, aFieldError will be raised:

# This will raise a FieldError>>>Entry.objects.update(headline=F("blog__name"))

Related objects

When you define a relationship in a model (i.e., aForeignKey,OneToOneField, orManyToManyField), instances of that model will havea convenient API to access the related object(s).

Using the models at the top of this page, for example, anEntry objecte can get its associatedBlog object by accessing theblogattribute:e.blog.

(Behind the scenes, this functionality is implemented by Pythondescriptors. This shouldn’t really matter toyou, but we point it out here for the curious.)

Django also creates API accessors for the “other” side of the relationship –the link from the related model to the model that defines the relationship.For example, aBlog objectb has access to a list of all relatedEntry objects via theentry_set attribute:b.entry_set.all().

All examples in this section use the sampleBlog,Author andEntrymodels defined at the top of this page.

One-to-many relationships

Forward

If a model has aForeignKey, instances of that modelwill have access to the related (foreign) object via an attribute of the model.

Example:

>>>e=Entry.objects.get(id=2)>>>e.blog# Returns the related Blog object.

You can get and set via a foreign-key attribute. As you may expect, changes tothe foreign key aren’t saved to the database until you callsave(). Example:

>>>e=Entry.objects.get(id=2)>>>e.blog=some_blog>>>e.save()

If aForeignKey field hasnull=True set (i.e.,it allowsNULL values), you can assignNone to remove the relation.Example:

>>>e=Entry.objects.get(id=2)>>>e.blog=None>>>e.save()# "UPDATE blog_entry SET blog_id = NULL ...;"

Forward access to one-to-many relationships is cached the first time therelated object is accessed. Subsequent accesses to the foreign key on the sameobject instance are cached. Example:

>>>e=Entry.objects.get(id=2)>>>print(e.blog)# Hits the database to retrieve the associated Blog.>>>print(e.blog)# Doesn't hit the database; uses cached version.

Note that theselect_related()QuerySet method recursively prepopulates thecache of all one-to-many relationships ahead of time. Example:

>>>e=Entry.objects.select_related().get(id=2)>>>print(e.blog)# Doesn't hit the database; uses cached version.>>>print(e.blog)# Doesn't hit the database; uses cached version.

Following relationships “backward”

If a model has aForeignKey, instances of theforeign-key model will have access to aManager thatreturns all instances of the first model. By default, thisManager is namedFOO_set, whereFOO is thesource model name, lowercased. ThisManager returnsQuerySet instances, which can be filtered and manipulated as described inthe “Retrieving objects” section above.

Example:

>>>b=Blog.objects.get(id=1)>>>b.entry_set.all()# Returns all Entry objects related to Blog.# b.entry_set is a Manager that returns QuerySets.>>>b.entry_set.filter(headline__contains="Lennon")>>>b.entry_set.count()

You can override theFOO_set name by setting therelated_name parameter in theForeignKey definition. For example, if theEntrymodel was altered toblog=ForeignKey(Blog,on_delete=models.CASCADE,related_name='entries'), the above example code would look like this:

>>>b=Blog.objects.get(id=1)>>>b.entries.all()# Returns all Entry objects related to Blog.# b.entries is a Manager that returns ``QuerySet`` instances.>>>b.entries.filter(headline__contains="Lennon")>>>b.entries.count()

Using a custom reverse manager

By default theRelatedManager usedfor reverse relations is a subclass of thedefault manager for that model. If you would like to specify a differentmanager for a given query you can use the following syntax:

fromdjango.dbimportmodelsclassEntry(models.Model):# ...objects=models.Manager()# Default Managerentries=EntryManager()# Custom Managerb=Blog.objects.get(id=1)b.entry_set(manager="entries").all()

IfEntryManager performed default filtering in itsget_queryset()method, that filtering would apply to theall() call.

Specifying a custom reverse manager also enables you to call its custommethods:

b.entry_set(manager="entries").is_published()

Interaction with prefetching

When callingprefetch_related() witha reverse relation, the default manager will be used. If you want toprefetch related objects using a custom reverse manager, usePrefetch(). For example:

fromdjango.db.modelsimportPrefetchprefetch_manager=Prefetch("entry_set",queryset=Entry.entries.all())Blog.objects.prefetch_related(prefetch_manager)

Additional methods to handle related objects

In addition to theQuerySet methods defined in“Retrieving objects” above, theForeignKeyManager has additional methods used to handle theset of related objects. A synopsis of each is below, and complete details canbe found in therelated objects reference.

add(obj1,obj2,...)

Adds the specified model objects to the related object set.

create(**kwargs)

Creates a new object, saves it and puts it in the related object set.Returns the newly created object.

remove(obj1,obj2,...)

Removes the specified model objects from the related object set.

clear()

Removes all objects from the related object set.

set(objs)

Replace the set of related objects.

To assign the members of a related set, use theset() method with aniterable of object instances. For example, ife1 ande2 areEntryinstances:

b=Blog.objects.get(id=1)b.entry_set.set([e1,e2])

If theclear() method is available, any preexisting objects will beremoved from theentry_set before all objects in the iterable (in thiscase, a list) are added to the set. If theclear() method isnotavailable, all objects in the iterable will be added without removing anyexisting elements.

Each “reverse” operation described in this section has an immediate effect onthe database. Every addition, creation and deletion is immediately andautomatically saved to the database.

Many-to-many relationships

Both ends of a many-to-many relationship get automatic API access to the otherend. The API works similar to a “backward” one-to-many relationship, above.

One difference is in the attribute naming: The model that defines theManyToManyField uses the attribute name of thatfield itself, whereas the “reverse” model uses the lowercased model name of theoriginal model, plus'_set' (just like reverse one-to-many relationships).

An example makes this easier to understand:

e=Entry.objects.get(id=3)e.authors.all()# Returns all Author objects for this Entry.e.authors.count()e.authors.filter(name__contains="John")a=Author.objects.get(id=5)a.entry_set.all()# Returns all Entry objects for this Author.

LikeForeignKey,ManyToManyField can specifyrelated_name. In the above example,if theManyToManyField inEntry had specifiedrelated_name='entries', then eachAuthor instance would have anentries attribute instead ofentry_set.

Another difference from one-to-many relationships is that in addition to modelinstances, theadd(),set(), andremove() methods on many-to-manyrelationships accept primary key values. For example, ife1 ande2 areEntry instances, then theseset() calls work identically:

a=Author.objects.get(id=5)a.entry_set.set([e1,e2])a.entry_set.set([e1.pk,e2.pk])

Filtering on many-to-many relationships

When callingfilter() on a many-to-many relationship, be aware that thejoin betweenEntry and the intermediary model toAuthor is performedonly once, resulting in a restrictive, or “sticky”, filter. Consider thefollowing example:

>>>fromdatetimeimportdate>>>batucada=Blog.objects.create(name="Batucada Blog")>>>e=Entry.objects.create(...blog=batucada,...headline="Supporting social movements with drums",...pub_date=date(2019,6,14),...)>>>gloria=Author.objects.create(name="Gloria")>>>anna=Author.objects.create(name="Anna")>>>e.authors.add(gloria,anna)>>>anna.entry_set.filter(authors__name="Gloria")<QuerySet []>

This filtered query is looking for blog entries that are co-authored byanna andgloria. You would expect it to return the entrye.However, the filter condition, which traverses the many-to-manyrelationship betweenEntry andAuthor, yields an emptyQuerySet.

Since the join betweenEntry and the intermediary model toAuthorhappens only once, no single object of the joined models - i.e., a relationbetween one author and one entry - can fulfill the query condition (entriesthat are co-authored byanna andgloria). You can circumvent thisbehavior by chaining two consecutivefilter() calls, resulting in twoseparate joins and thus a more permissive filter:

>>>anna.entry_set.filter().filter(authors__name="Gloria")<QuerySet [<Entry: Supporting social movements with drums>]>

exclude() is also sticky

Please note that for this example,exclude() behaves similarlytofilter() despite beingimplemented differently. When traversing the many-to-many relationship,it does not exclude the entrye despite being co-authored by Gloria:

>>>anna.entry_set.exclude(authors__name="Gloria")<QuerySet [<Entry: Supporting social movements with drums>]>

When chaining a secondexclude() call, an emptyQuerySet isreturned, as expected:

>>>anna.entry_set.exclude().exclude(authors__name="Gloria")<QuerySet []>

However, in other cases,exclude()behaves differently fromfilter().See thenote in the “Spanning multi-valuedrelationships” section above.

One-to-one relationships

One-to-one relationships are very similar to many-to-one relationships. If youdefine aOneToOneField on your model, instances ofthat model will have access to the related object via an attribute of themodel.

For example:

classEntryDetail(models.Model):entry=models.OneToOneField(Entry,on_delete=models.CASCADE)details=models.TextField()ed=EntryDetail.objects.get(id=2)ed.entry# Returns the related Entry object.

The difference comes in “reverse” queries. The related model in a one-to-onerelationship also has access to aManager object,but thatManager represents a single object, ratherthan a collection of objects:

e=Entry.objects.get(id=2)e.entrydetail# returns the related EntryDetail object

If no object has been assigned to this relationship, Django will raiseaDoesNotExist exception.

Instances can be assigned to the reverse relationship in the same way asyou would assign the forward relationship:

e.entrydetail=ed

How are the backward relationships possible?

Other object-relational mappers require you to define relationships on bothsides. The Django developers believe this is a violation of the DRY (Don’tRepeat Yourself) principle, so Django only requires you to define therelationship on one end.

But how is this possible, given that a model class doesn’t know which othermodel classes are related to it until those other model classes are loaded?

The answer lies in theappregistry. When Djangostarts, it imports each application listed inINSTALLED_APPS, andthen themodels module inside each application. Whenever a new model classis created, Django adds backward-relationships to any related models. If therelated models haven’t been imported yet, Django keeps tracks of therelationships and adds them when the related models eventually are imported.

For this reason, it’s particularly important that all the models you’re usingbe defined in applications listed inINSTALLED_APPS. Otherwise,backwards relations may not work properly.

Queries over related objects

Queries involving related objects follow the same rules as queries involvingnormal value fields. When specifying the value for a query to match, you mayuse either an object instance itself, or the primary key value for the object.

For example, if you have a Blog objectb withid=5, the followingthree queries would be identical:

Entry.objects.filter(blog=b)# Query using object instanceEntry.objects.filter(blog=b.id)# Query using id from instanceEntry.objects.filter(blog=5)# Query using id directly

Falling back to raw SQL

If you find yourself needing to write an SQL query that is too complex forDjango’s database-mapper to handle, you can fall back on writing SQL by hand.Django has a couple of options for writing raw SQL queries; seePerforming raw SQL queries.

Finally, it’s important to note that the Django database layer is merely aninterface to your database. You can access your database via other tools,programming languages or database frameworks; there’s nothing Django-specificabout your database.

Back to Top

Additional Information

Support Django!

Support Django!

Contents

Getting help

FAQ
Try the FAQ — it's got answers to many common questions.
Index,Module Index, orTable of Contents
Handy when looking for specific information.
Django Discord Server
Join the Django Discord Community.
Official Django Forum
Join the community on the Django Forum.
Ticket tracker
Report bugs with Django or Django documentation in our ticket tracker.

Download:

Offline (Django 6.0):HTML |PDF |ePub
Provided byRead the Docs.

Diamond and Platinum Members

Sentry
JetBrains

[8]ページ先頭

©2009-2025 Movatter.jp