Master Django ORM: Advanced Foreign Key Queries & Reverse Lookups

This article walks through Django ORM's advanced query techniques, covering foreign‑key field access, reverse lookups with __set and related_name, double‑underscore cross‑table filters, values and values_list usage, and chaining multiple filter calls for flexible data retrieval.

Python Crawling & Data Mining
Python Crawling & Data Mining
Python Crawling & Data Mining
Master Django ORM: Advanced Foreign Key Queries & Reverse Lookups

Review

Previously we covered the basic filter() query operation in Django ORM.

Query Operations

Object.foreign_key_field

When we have a Book instance, we can print its related fields directly.

book = models.Book.objects.filter(title="<<大明帝国>>").first()
print(f"book type: {type(book)}")
print(f"id: {book.id}")
print(f"title: {book.title}")
print(f"price: {book.price}")
print(f"publish date: {book.PublishDate}")
print(f"publisher: {book.publish}")  # foreign‑key field

Result

Note: the blue text indicates a foreign‑key field.

The reason book.publish prints the publisher name is that the Publish model defines __str__ to return self.title. To access other publisher attributes, we can use the foreign‑key object directly.

print(f"Publisher type: {type(book.publish)}")  # <class 'web.models.Publish'>
print(f"Publisher phone: {book.publish.phone},")

Reverse Query (model__set.all())

We can retrieve all books belonging to a specific publisher by first obtaining the publisher object and then using the reverse relation.

# Query publisher
publish_obj = models.Publish.objects.filter(title="邮电出版社").first()
# Get publisher id
publish_id = publish_obj.id
# Find books with that publisher id
book_list = models.Book.objects.filter(publish_id=publish_id)
print(book_list)

Alternatively, Django provides a shortcut using the reverse manager:

publish_obj = models.Publish.objects.filter(title="邮电出版社").first()
book_list = publish_obj.book_set.all()
print(book_list)

Double‑Underscore Cross‑Table Query

Using the double‑underscore syntax we can filter books by a publisher's title in a single query.

book_list = models.Book.objects.filter(publish__title="邮电出版社")
print(book_list)

The double‑underscore can also be chained for multi‑table lookups, e.g., retrieving books and their many‑to‑many authors through the publisher:

ret = models.BookManyAuthor.objects.filter(book__publish__title="邮电出版社")
print(ret)

values

When only specific columns are needed, values() returns dictionaries of the selected fields.

# Syntax
book_list = models.Book.objects.all().values("title", "price")
print(book_list)

values_list

values_list()

works like values() but returns tuples instead of dictionaries.

book_list = models.Book.objects.all().values_list("title", "price")
print(book_list)

related_name

The related_name attribute customizes the reverse manager name, replacing the default model_set.

Original way (using book_set):

publish = models.Publish.objects.filter(title="邮电出版社").first()
book_list = publish.book_set.all()
print(book_list)

Alias way (using book_list as defined by related_name='book_list'):

publish = models.Publish.objects.filter(title="邮电出版社").first()
book_list = publish.book_list.all()
print(book_list)

Chaining Multiple filter() Calls

Multiple filter() calls can be chained to apply successive conditions, useful when filter criteria are built dynamically.

book1 = models.Book.objects.filter(title="<<大明帝国>>").filter(price="99")
book2 = models.Book.objects.filter(title="<<大明帝国>>", price="99")
print(book1)
print(book2)

Summary

This article extends the previous discussion on filter queries, focusing on foreign‑key field access, reverse lookups using the default model__set and custom related_name, double‑underscore cross‑table filters, chained filters, and the differences between values and values_list.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PythonDjangoORMForeignKeyReverse Lookup
Python Crawling & Data Mining
Written by

Python Crawling & Data Mining

Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.