Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

django

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!

like image 453
Geradeausanwalt Avatar asked Jan 14 '10 13:01

Geradeausanwalt


People also ask

How do you create an instance of a model from another model in Django?

To create a new instance of a model, instantiate it like any other Python class: class Model (**kwargs) The keyword arguments are the names of the fields you've defined on your model. Note that instantiating a model in no way touches your database; for that, you need to save() .

Can we inherit model in Django?

Models inheritance works the same way as normal Python class inheritance works, the only difference is, whether we want the parent models to have their own table in the database or not. When the parent model tables are not created as tables it just acts as a container for common fields and methods.

What is __ str __ in Django?

The __str__ method just tells Django what to print when it needs to print out an instance of the any model.

What is Get_absolute_url in Django?

Django documentation says: get_absolute_url() method to tell Django how to calculate the canonical URL for an object.


1 Answers

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.

like image 180
Will Hardy Avatar answered Sep 20 '22 16:09

Will Hardy