Django select field with thousands of choices creating thousands of database queries
unicode gets a field from these other models (self.foreign_key_field.field_to_print_out).

This is where the other queries are made, not from the call to unicode or checking if its a b or a c.
Had your unicode method reference only local fields this wouldn't have been an issue, but as you have noticed fields that require a join are not done automatically to save some performance on things that may not even be required.
If you use django-debug-toolbar, you should notice that the 1000 queries are the retrieval of the related object, not the list of a objects.
So yes, as you've pointed out, select_related would help here since this is you telling django that you do require these fields.
I have two models, model B and model C, which both extend model A. 
In a form I have a model select field for model A - this obviously loads all instances of model B and C which was my intention. 
So this dropdown is over 1000 'A Objects'. I am using hasattr() to determine if they're B or C, which then uses the unicode method from those classes to display the object in string from in the dropdown.
This creates thousands of SQL queries which takes around a minute to process. Right now my solution is to query the database 3 times (to get all A, B and C objects, and then loop over A and decide if each oject is of type B or C and push the correct unicode string into a list which is used in the dropdown. I then clean the data and select the right object when saving the form. This is hackey (to me). 
I was wondering if anyone knows of an efficient way of populating a dropdown with thousands of model object choices when that model is a Base Model for other models. 
Cheers,
Dean