Django ListView with MySQL query for the queryset
This is slow NOT because of your SQL.
The SQL in the post is a simple JOIN,
on id columns that are indexed by Django by default.

Without doubt, the cause of the slowness is this:


for row in queryset:
    pizza = Pizza.objects.get(id=row['pizza_id'])
    topping = Topping.objects.get(id=row['topping_id'])



For every row returned by the first query,
you load a Pizza and a Topping.
Django might be smart enough to not re-fetch the same topping multiple times,
but for every unique Pizza and every unique Topping,
Django will have to run an additional query.
With 700 pizzas, you're looking at at least 700 queries, which is clearly not efficient.


  Unfortunately, I can't just use Django's helpfulness and just give it the model to use (I'm skipping why for the sake of brevity)


It would be best to get to the bottom of this. 
Take a look at the documentation of the select_related method on querysets,
I think the solution for your case should be somewhere around there.
I really think there's a solution within the realm of "Django's helpfulness",
without resorting to such queries, you just need to figure it out.
(You might want to ask some questions on that on stackoverflow.com)

Another workaround might be to stop calling Pizza.objects.get and Topping.objects.get:
include in your query all the fields you need for pizzas and toppings,
and build simple dictionaries from them.
Rest assured, when you stop calling Pizza.objects.get and Topping.objects.get 700 times you will notice a massive speed improvement.