W1ck3d
W1ck3d

Reputation: 334

Best way of checking whether a certain Model instance is in fact an instance of a certain Model

I am trying to write a class that takes an instance of a Model from my app as an argument in its __init__. While reading up on the subject, I stumbled upon this quesiton: django: best practice way to get model from an instance of that model which argues that simply using type(instance) would be the best way to go. As tempting as it may be to use this right away, wouldn't using isinstance(instance, model) be a better solution? Say, for example (from my own code):

from app_name.models import Model1, Model2, ... ModelN
MODELS = (Model1, Model2 ... ModelN)

and then inside the class itself (in my case, Graph), do something like this:

class Graph():
    model_instance = None
    model = None
    def __init__(self, model_instance):
        if isinstance(model_instance, MODELS):
            for a_model in MODELS:
                if isinstance(model_instance, a_model):
                    self.model = a_model
            self.model_instance = model_instance
...

As a beginner, I thought this was the best way I could come up with but also assume there are smoother/better ways of doing this. Possibly an even more "readable" way maybe? Pros? Cons?

Appreciate ALL feedback on this! Thanks!

Those interested in the whole context of this question, please check out my project on GitHub: https://github.com/VBoB13/TeachAdmin You can find the file with above code here: https://github.com/VBoB13/TeachAdmin/blob/master/teachadmin/graph.py

Upvotes: 2

Views: 2222

Answers (1)

iklinac
iklinac

Reputation: 15728

From isinstance documentation

Return True if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof. If object is not an object of the given type, the function always returns False. If classinfo is a tuple of type objects (or recursively, other such tuples), return True if object is an instance of any of the types. If classinfo is not a type or tuple of types and such tuples, a TypeError exception is raised.

This would mean that if you have model that is subclass of another one that they will both be marked as instance of superclass

For example :

class A(object):
  pass

class B(A):
  pass

a = A()
b = B() 

print(isinstance(b,A))
# True
print(type(b)==type(A())
# False

In conclusion you should use type() as there are multiple ways to use model inheritance in Django which could yield wrong type class results

Upvotes: 2

Related Questions