django: best practice way to get model from an instance of that model

Django

Django Problem Overview


Say my_instance is of model MyModel.
I'm looking for a good way to do:

my_model = get_model_for_instance(my_instance)

I have not found any really direct way to do this. So far I have come up with this:

from django.db.models import get_model

my_model = get_model(my_instance._meta.app_label, my_instance.__class__.__name__)

Is this acceptable? Is it even a sure-fire, best practice way to do it?
There is also _meta.object_name which seems to deliver the same as __class__.__name__. Does it? Is better or worse? If so, why?

Also, how do I know I'm getting the correct model if the app label occurs multiple times within the scope of the project, e.g. 'auth' from 'django.contrib.auth' and let there also be 'myproject.auth'?
Would such a case make get_model unreliable?

Thanks for any hints/pointers and sharing of experience!

Django Solutions


Solution 1 - Django

my_model = type(my_instance)

To prove it, you can create another instance:

my_new_instance = type(my_instance)()

This is why there's no direct way of doing it, because python objects already have this feature.

updated...

I liked marcinn's response that uses type(x). This is identical to what the original answer used (x.__class__), but I prefer using functions over accessing magic attribtues. In this manner, I prefer using vars(x) to x.__dict__, len(x) to x.__len__ and so on.

updated 2...

For deferred instances (mentioned by @Cerin in comments) you can access the original class via instance._meta.proxy_for_model.

Solution 2 - Django

my_new_instance = type(my_instance)()

Solution 3 - Django

At least for Django 1.11, this should work (also for deferred instances):

def get_model_for_instance(instance):
    return instance._meta.model

Source here.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGeradeausanwaltView Question on Stackoverflow
Solution 1 - DjangoWill HardyView Answer on Stackoverflow
Solution 2 - DjangomarcinnView Answer on Stackoverflow
Solution 3 - DjangoRockalliteView Answer on Stackoverflow