Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Django cache related ForeignKey and ManyToManyField fields once they're accessed?

Given the following model, does Django cache the related objects after the first time they're accessed?

class Post(models.Model):
    authors = models.ManyToManyField(User)
    category = models.ForeignKey(Category)

For example:

post = Post.objects.get(id=1)

# as i understand this hits the database
authors1 = post.authors.all()
# does this his the database again?
authors2 = post.authors.all()

# as i understand this hits the database
category1 = post.category
# does this hit the database again?
category2 = post.category

Note: currently working with Django 1.3, but it's good to know what's available in other versions.

like image 803
bpscott Avatar asked Nov 29 '11 19:11

bpscott


People also ask

How does Django caching work?

Unless we explicitly specify another caching method in our settings file, Django defaults to local memory caching. As its name implies, this method stores cached data in RAM on the machine where Django is running. Local memory caching is fast, responsive, and thread-safe.

Where is Django cache stored?

If you're building your own backend, you can use the standard cache backends as reference implementations. You'll find the code in the django/core/cache/backends/ directory of the Django source.

What type of caching mechanism does Django support?

Memcached. This is the most efficient caching system supported natively in Django. Memcached provides a fast interface for adding, retrieving, and deleting data from the cache. Here, all data are stored directly in memory instead of the database, which makes accessing the data faster.

How does Django handle many to many relationships?

Behind the scenes, Django creates an intermediary join table to represent the many-to-many relationship. By default, this table name is generated using the name of the many-to-many field and the name of the table for the model that contains it.


1 Answers

In the first example the second query is cached. In the second case (I believe) they will both cause a DB hit unless you use select_related on the original query:

post = Post.objects.select_related('category').get(id=1)

EDIT

I'm wrong about the second example. If you use select_related in the original query, you won't hit the database at all again (The ForeignKey is cached immediately). If you don't use select_related, you will hit the DB on the first query but the second query will be cached.

From:

https://docs.djangoproject.com/en/dev/topics/db/queries/#one-to-many-relationships

Forward access to one-to-many relationships is cached the first time the related object is accessed. Subsequent accesses to the foreign key on the same object instance are cached.

Note that the select_related() QuerySet method recursively prepopulates the cache of all one-to-many relationships ahead of time.

like image 89
Timmy O'Mahony Avatar answered Sep 28 '22 23:09

Timmy O'Mahony