web-dev-qa-db-fra.com

Django obtenir la liste des modèles dans l'application

Donc, j'ai un fichier models.py dans le dossier MyApp:

from Django.db import models
class Model_One(models.Model):
    ...
class Model_Two(models.Model):
    ...
...

Il peut s'agir de 10 à 15 classes. Comment trouver tous les modèles dans MyApp et obtenir leurs noms?

Comme les modèles ne sont pas itérables, je ne sais pas si c'est même possible.

53
Feanor

MISE À JOUR

pour les versions plus récentes de Django check ( Sjoerd réponse ci-dessous

Réponse originale de 2012: c'est la meilleure façon d'accomplir ce que vous voulez faire:

from Django.db.models import get_app, get_models

app = get_app('my_application_name')
for model in get_models(app):
    # do something with the model

Dans cet exemple, model est le modèle réel, vous pouvez donc faire plein de choses avec:

for model in get_models(app):
    new_object = model() # Create an instance of that model
    model.objects.filter(...) # Query the objects of that model
    model._meta.db_table # Get the name of the model in the database
    model._meta.verbose_name # Get a verbose name of the model
    # ...
84
juliomalegria

A partir de Django 1.7 sur, vous pouvez utiliser ce code, par exemple dans votre admin.py pour enregistrer tous les modèles:

from Django.apps import apps
from Django.contrib import admin
from Django.contrib.admin.sites import AlreadyRegistered

app_models = apps.get_app_config('my_app').get_models()
for model in app_models:
    try:
        admin.site.register(model)
    except AlreadyRegistered:
        pass
63
Sjoerd

Meilleure réponse que j'ai trouvée pour obtenir tous les modèles d'une application:

from Django.apps import apps
apps.all_models['<app_name>']  #returns dict with all models you defined
13
pedrotorres

Une alternative consiste à utiliser Types de conten .

Chaque modèle pour chaque application dans INSTALLED_APPS obtient une entrée dans les modèles ContentType. Cela vous permet, par exemple, d'avoir une clé étrangère vers un modèle.

>>> from Django.contrib.contenttypes.models import ContentType
>>> ContentType.objects.filter(app_label="auth")
<QuerySet [<ContentType: group>, <ContentType: permission>, <ContentType: user>]>
>>> [ct.model_class() for ct in ContentType.objects.filter(app_label="auth")]
[<class 'Django.contrib.auth.models.Group'>, <class 'Django.contrib.auth.models.Permission'>, <class 'Django.contrib.auth.models.User'>]
3
gkr

Voici une solution rapide et sale, sans codage, utilisant dumpdata et jq:

python manage.py dumpdata oauth2_provider | jq -r '.[] | .model' | uniq

Vous pouvez également nettoyer la commande jq pour obtenir le format à votre convenance.


Bonus: vous pouvez voir le nombre de différents types d'objets en ajoutant le -c drapeau à uniq.

1
mgalgs

Cela imprime des commandes pour vider les appareils pour tous les objets de votre projet. Vous devez copier votre liste d'applications à partir de votre fichier de paramètres. (J'ai déplacé mes applications dans un répertoire apps.)

from Django.apps import apps

print(
    '\n'.join(
        [
            '\n'.join(
                [
                    f'PYTHONPATH=.:apps Django-admin dumpdata {app}.{model} --settings=my_project.settings > apps/{app}/fixtures/{model}.json'
                    for model in apps.all_models[app]
                ]
            )
            for app in [
                'my_app',
                'my_other_app',
            ]
        ]
    )
)

Vérifiez que vous avez activé votre environnement virtuel afin d'utiliser le bon Django-admin. (Vérifier avec which Django-admin.py.)

Seulement lié tangentiellement à la question d'origine, mais pourrait être utile pour quelqu'un qui tombe dessus pour la même raison que moi. Je suis sur Django 2.2.4, je ne l'ai pas testé ailleurs.

0
Chris