Skip to main content

Expanding

Expanding means querying nested objects. Normally, Schedjuice only returns foreign keys for relationships. If you want to retrieve the whole object, you need to set the expand parameter in the url query param. See here for more details.

Relationship nomenclature

There are 3 types of relationships to consider:

  • one-to-one
  • many-to-one
  • one-to-many

For one-to-one relationships, the related field name is the same as the model name.

For many-to-one relationships, the related field name should exist on the model. (meaning, the Book model should already have the author field)

For one-to-many relationships, the related field name is in this pattern: f"{field_name}_set".

A simple example

Consider a database having two tables Book and Author.

It includes the following books:

idtitleauthor
1A Brief History of Time1
2The Lord of the Rings2
3The Hobbit2

And these authors:

idnameis_alive
1Stephen Hawkingsfalse
2J. R. R. Tolkienfalse

Querying to /books will yield:

[
{
"id": 1,
"title": "A Brief History of Time",
"author": 1
},
{
"id": 2,
"title": "The Lord of the Rings",
"author": 2
},
{
"id": 3,
"title": "The Hobbit",
"author": 2
}
]

If you want the author field to be populated, your query will look like this: /books?expand=["author"] (the expand param has to be base64 encoded).

[
{
"id": 1,
"title": "A Brief History of Time",
"author": {
"id": 1,
"name": "Stephen Hawkings",
"is_alive": false
}
},
{
"id": 2,
"title": "The Lord of the Rings",
"author": {
"id": 2,
"name": "J. R. R. Tolkien",
"is_alive": false
}
},
{
"id": 3,
"title": "The Hobbit",
"author": {
"id": 2,
"name": "J. R. R. Tolkien",
"is_alive": false
}
}
]

A normal query to /authors will yield this result. Notice here that there is no sign of foreign relationships unlike our previous model.

[
{
"id": 1,
"name": "Stephen Hawkings",
"is_alive": false
},
{
"id": 2,
"name": "J. R. R. Tolkien",
"is_alive": false
}
]

If you want to query the list of books, your query will look like this: /authors?expand=["book_set"]. Thus, yielding:

[
{
"id": 1,
"name": "Stephen Hawkings",
"is_alive": false,
"book_set": [
{
"id": 1,
"title": "A Brief History of Time",
"author": 1
}
]
},
{
"id": 2,
"name": "J. R. R. Tolkien",
"is_alive": false,
"book_set": [
{
"id": 2,
"title": "The Lord of the Rings",
"author": 2
},
{
"id": 3,
"title": "The Hobbit",
"author": 2
}
]
}
]

You can take a step further and make this request: /authors?expand=["book_set", "book_set.author"].

[
{
"id": 1,
"name": "Stephen Hawkings",
"is_alive": false,
"book_set": [
{
"id": 1,
"title": "A Brief History of Time",
"author": {
"id": 1,
"name": "Stephen Hawkings",
"is_alive": false
}
}
]
},
{
"id": 2,
"name": "J. R. R. Tolkien",
"is_alive": false,
"book_set": [
{
"id": 2,
"title": "The Lord of the Rings",
"author": {
"id": 2,
"name": "J. R. R. Tolkien",
"is_alive": false
}
},
{
"id": 3,
"title": "The Hobbit",
"author": {
"id": 2,
"name": "J. R. R. Tolkien",
"is_alive": false
}
}
]
}
]

This is of course completely useless for this case.

Nest as much as you want

Nesting is not limited to only dept of 1. You can query the grandchildren and great-grandchildren as well. However, do be mindful about the performance issues.

Errors are silent

Supplying a non-existent field name will not raise any errors.

This is implemented using drf-ff, for more information see its docs here.