﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
21519	django.db.models: get_apps() includes abstract models, get_models() excludes them	Aaron Adams	nobody	"(I'm uncertain how much of this report is bug vs. new feature; I went with the latter for now.)

From the `BaseAppCache` class in [https://github.com/django/django/blob/master/django/db/models/loading.py django.db.models.loading]:

{{{
    def get_apps(self):
        """"""
        Returns a list of all installed modules that contain models.
        """"""
}}}

When `get_apps()` says ""all installed modules that contain models"", it really means it: the returned list includes modules containing only abstract base class models.

{{{
    def get_models(self, app_mod=None,
                   include_auto_created=False, include_deferred=False,
                   only_installed=True, include_swapped=False):
        """"""
        Given a module containing models, returns a list of the models.
        Otherwise returns a list of all installed models.

        ...
        """"""
}}}

`get_models()` doesn't give any indication that it should work any differently; yet it ignores abstract base class models, returning a list of concrete models only.

This inconsistency is very counter-intuitive:

{{{
>>> from django.db import models
>>> [{app: models.get_models(app)} for app in models.get_apps()]
[{<module 'django.contrib.admin.models'>: [<class 'django.contrib.admin.models.LogEntry'>]},
 {<module 'django.contrib.auth.models'>: [<class 'django.contrib.auth.models.Permission'>,
                                          <class 'django.contrib.auth.models.Group'>,
                                          <class 'django.contrib.auth.models.User'>]},
 {<module 'django.contrib.contenttypes.models'>: [<class 'django.contrib.contenttypes.models.ContentType'>]},
 {<module 'django.contrib.sessions.models'>: [<class 'django.contrib.sessions.models.Session'>]},
 {<module 'django.contrib.messages.models'>: []},
 {<module 'django.contrib.staticfiles.models'>: []},
 {<module 'myapp.models'>: [<class 'myapp.models.ConcreteModel'>]},
 {<module 'myapputils.models'>: []}]
}}}

`get_apps()` says an app contains models, but passing that app to `get_models()` returns an empty list.

The docs indicate that yes, [https://docs.djangoproject.com/en/dev/ref/models/options/#abstract an abstract base class is a model]; so I think `get_models()` should return them, or at least should be ''able'' to return them with an `include_abstract=True` argument.

(The use case is `graph_models` in `django_extensions`, which outputs a [http://www.graphviz.org/ Graphviz] digraph of the models in an application or project. Currently it's forced to walk up the model tree to find abstract base classes, leading to some unexpected behaviours that would be much easier to resolve without this Django quirk.)"	New feature	closed	Database layer (models, ORM)	dev	Normal	wontfix			Unreviewed	0	0	0	0	0	0
