Django ORM Queries in the Shell
In the last year I took over a Django project with about 200k LOC. The team and I have since added almost 100k more LOC in new features. Accordingly, the complexity of our Django models has grown significantly.
Much of the time, when I’m looking to add a new feature, I’ll run through the relationships between models in the shell. It has saved me a ton of headaches and makes working with Django that much more enjoyable.
Here’s how easy it is to jump into the shell and explore your data:
Since I use docker to containerize all my projects, the first couple steps are docker specific.
Navigate to the docker container
First, start up your app.
docker-compose up
Next, find all the running processes.
docker ps
The output will look something like this:
Find the CONTAINER_ID that matches the server for your django app. Then execute this command to navigate into the terminal for the correct container:
docker exec -it CONTAINER_ID bash
And finally
./manage.py shell
Amazing. And now we’re inside the python shell and can start playing with our database. Here’s some example queries that might be useful to start off with.
from ecommerce.api.models import Item, Cart
Item.objects.all()
item = Item.objects.get(pk=1)
cart = Cart()
cart.add_item(item)
cart.show_items()
Or for a different different app…
from sports_team.api.models import Player, Team
Team.objects.all()
team = Team()
player1 = Player('Jeff')
player2 = Player('Shadira')
player3 = Player('Jenny')
team.add_members([player1, player2, player3])
team.display_members()
Want to get down to some raw SQL? No problem
user_profiles = UserProfile.objects.raw('SELECT * FROM project_user_profile')
for profile in user_profiles: print(profile)
WARNING: No checking is done on the SQL statement that is passed in to .raw(). Django expects that the statement will return a set of rows from the database, but does nothing to enforce that. If the query does not return rows, a (possibly cryptic) error will result.