Django ORM - Order of query evaluation

When working with an ORM it is often easy to forget that whatever you write is ultimately translated to SQL queries.

Consider this script:

bookings = task.contractor.bookings.all()
task.delete()
bookings.delete()

This will run with no errors.

As you would expecttask will be deleted, however the bookings will persist in the db! What's going on?

The code above will result in 2 SQL queries:

  1. One that deletes the task based on the task id
  2. One that deletes bookings that appear as a foreign key to the related contractor table, via the related tasks table filtered by... the same task id that was just deleted!

As the task is deleted in the 1st query, then the 2nd query will yield no results (as the specific task id will no longer exist).

For this to work we just need to reverse the order of operations:

bookings = task.contractor.bookings.all()
bookings.delete()
task.delete()