姜戈: 我怎样才能找到 ORM 知道的模型列表?

在 Django 中,有没有一个地方我可以获得 ORM 所知道的模型列表或者查找这些模型?

40513 次浏览

If you use the contenttypes app, then it is straightforward: http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/

If you want to play, and not use the good solution, you can play a bit with python introspection:

import settings
from django.db import models


for app in settings.INSTALLED_APPS:
models_name = app + ".models"
try:
models_module = __import__(models_name, fromlist=["models"])
attributes = dir(models_module)
for attr in attributes:
try:
attrib = models_module.__getattribute__(attr)
if issubclass(attrib, models.Model) and attrib.__module__== models_name:
print "%s.%s" % (models_name, attr)
except TypeError, e:
pass
except ImportError, e:
pass

Note: this is quite a rough piece of code; it will assume that all models are defined in "models.py" and that they inherit from django.db.models.Model.

Simple solution:

import django.apps
django.apps.apps.get_models()

By default apps.get_models() don't include

  • auto-created models for many-to-many relations without an explicit intermediate table
  • models that have been swapped out.

If you want to include these as well,

django.apps.apps.get_models(include_auto_created=True, include_swapped=True)

Prior to Django 1.7, instead use:

from django.db import models
models.get_models(include_auto_created=True)

The include_auto_created parameter ensures that through tables implicitly created by ManyToManyFields will be retrieved as well.

If you register your models with the admin app, you can see all the attributes of these classes in the admin documentation.

List models using http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/

from django.contrib.contenttypes.models import ContentType


for ct in ContentType.objects.all():
m = ct.model_class()
print "%s.%s\t%d" % (m.__module__, m.__name__, m._default_manager.count())

Here's a simple way to find and delete any permissions that exist in the database but don't exist in the ORM model definitions:

from django.apps import apps
from django.contrib.auth.management import _get_all_permissions
from django.contrib.auth.models import Permission
from django.core.management.base import BaseCommand




class Command(BaseCommand):
def handle(self, *args, **options):
builtins = []
for klass in apps.get_models():
for perm in _get_all_permissions(klass._meta):
builtins.append(perm[0])
builtins = set(builtins)


permissions = set(Permission.objects.all().values_list('codename', flat=True))
to_remove = permissions - builtins
res = Permission.objects.filter(codename__in=to_remove).delete()
self.stdout.write('Deleted records: ' + str(res))

If you want a dictionary with all models you can use:

from django.apps import apps


models = {
model.__name__: model for model in apps.get_models()
}