Setting an attribute on object's __class__ attribute
Yes, that is setting the attribute on the class. But no, that would not necessarily make it available between requests, although it might.
Your question shows a misunderstanding of how Django requests work. Django is not necessarily served using multiple threads: in fact, in most server configuration, it is hosted by multiple independent processes that are managed by the server. Again, depending on the configuration, each of those processes may or may not have multiple threads. But whether or not threads are involved, processes are started and killed by the server all the time.
If you set an attribute on a class or module in Django during one request, any subsequent requests served by that same process will see that attribute. But there's no way to guarantee which process your next request will be served by. And there's certainly no way to know if the same user will be accessing the next request from that same process. 
Setting things at class or module level can be the source of some very nasty thread-safety bugs. My advice is generally not to do it. If you need to keep things across request, store it in the database, the cache, or (especially if it's specific to a particular user) in the session.
I am a bit confused over the difference between setting an object's attribute and setting an attribute on an object's __class__ attribute. Roughly, obj.attr vs obj.__class__.attr. What's the difference between them?
Is the former setting an attribute on an instance and the latter setting an attribute on an instance's class (making that attribute available to all instances)? If this is the case, then how are these new class attributes available in Django requests, since the framework works with multiple threads? Does setting a class variable make it persist between requests?