11

If a django model is made abstract, like below, is there a way to inspect the class to determine that it is abstract?

class MyModel(models.Model):
  class Meta:
    abstract = True

I would expect that I could examine MyModel.Meta.abstract, but according to Django docs:

Django does make one adjustment to the Meta class of an abstract base class: before installing the Meta attribute, it sets abstract=False. This means that children of abstract base classes don't automatically become abstract classes themselves.

Any ideas? Thanks!

Nagyman
  • 599
  • 4
  • 8
  • What's wrong with reading the source? It's always available. – S.Lott Nov 20 '09 at 21:03
  • The abstract from docs is related to derived class' Meta, not base's. – Dmitry Risenberg Nov 21 '09 at 00:18
  • 1
    @S.Lott - Indeed, I RTFM but failed to RTFS. To be fair, many of the questions on S.O. could probably be self-answered by reading the source. @Dmitry - I'm a bit confused by your comment. From django/db/basy.py, it appears that all of the attributes in the Meta class are transferred to a new class referenced as _meta. It's this class that holds the original abstract value set in models' Meta classes. Regardless, @sheats answered my question (Thanks again). – Nagyman Nov 23 '09 at 19:14

2 Answers2

16

You can instantiate MyModel and then check ._meta.abstract.

So in code:

m = MyModel()
print m._meta.abstract
sheats
  • 33,062
  • 15
  • 45
  • 44
  • I didn't spot that in dir(MyModel), but it's there. Thanks very much. – Nagyman Nov 20 '09 at 20:14
  • 1
    If you haven't looked into iPython I would strongly suggest it. It is very useful for playing around and finding out these things since it offers auto-completion. That's how I found this one =) – sheats Nov 20 '09 at 22:22
  • Is it normal to access to a protected member from outside in Python? – sergzach Apr 11 '12 at 15:34
3

I'd like to point out that you don't need to instantiate a model to check if it's abstract - Django models inherit an actual metaclass that adds _meta on class instantiation.

So, similarly to @sheats's code, try

from django.db.models import Model
class MyModel(Model):
  pass
print MyModel._meta.abstract

Or, for a positive example

from django.db.models import Model
class MyModel(Model):
  class Meta(object):
    abstract = True
print MyModel._meta.abstract

Of course, this also works for built-in models and anything inheriting from Django's Model.

from django.contrib.auth.models import User
print User._meta.abstract
Matt Luongo
  • 14,371
  • 6
  • 53
  • 64