182 votes

Django: Obtenir le modèle de la chaîne?

Dans Django, vous pouvez spécifier des relations telles que:

 author = ForeignKey('Person')
 

Et ensuite, en interne, il doit convertir la chaîne "Person" dans le modèle Person .

Où est la fonction qui fait ça? Je veux l'utiliser, mais je ne le trouve pas.

198voto

Mark Points 49079

Je l'ai trouvé C'est défini ici:

 from django.db.models.loading import get_model
 

Défini comme:

 def get_model(self, app_label, model_name, seed_cache=True):
 

174voto

Scott Woodall Points 2268

À partir de Django 1.7, les django.db.models.loading sont obsolètes (à supprimer dans la version 1.9) au profit du nouveau système de chargement d'applications. La documentation 1.7 nous donne plutôt les informations suivantes:

 $ python manage.py shell
Python 2.7.6 (default, Mar  5 2014, 10:59:47)
>>> from django.apps import apps
>>> auth = apps.get_app_config('auth')
>>> User = auth.get_model('User')
>>> print User
<class 'django.contrib.auth.models.User'>
>>>
 

88voto

user171654 Points 26

juste pour tous ceux qui sont coincés

 model_name = get_model('app_name', 'model_name')
 

app_name doit être répertorié avec des guillemets, de même que 'model_name' (c'est-à-dire n'essayez pas de l'importer)

get_model accepte les 'minuscules ou majuscules' nom_du_modèle '

34voto

Ch'marr Points 604

La plupart des modèle de "chaînes" apparaissent comme la forme "appname.modelname" alors vous voudrez utiliser cette variation sur get_model

from django.db.models.loading import get_model

your_model = get_model ( *your_string.split('.',1) )

La partie de l'django code qui tourne habituellement ces chaînes dans un modèle est un peu plus complexe à partir d' django/db/models/fields/related.py:

    try:
        app_label, model_name = relation.split(".")
    except ValueError:
        # If we can't split, assume a model in current app
        app_label = cls._meta.app_label
        model_name = relation
    except AttributeError:
        # If it doesn't have a split it's actually a model class
        app_label = relation._meta.app_label
        model_name = relation._meta.object_name

# Try to look up the related model, and if it's already loaded resolve the
# string right away. If get_model returns None, it means that the related
# model isn't loaded yet, so we need to pend the relation until the class
# is prepared.
model = get_model(app_label, model_name,
                  seed_cache=False, only_installed=False)

Pour moi, cela semble être une bonne affaire pour la division de cette dans une seule fonction dans le code de base. Toutefois, si vous savez que vos chaînes sont dans "App.Modèle", les deux liner ci-dessus va travailler.

4voto

jbcurtin Points 899

Je ne sais pas où cela se passe à Django, mais vous pouvez le faire.

Mapper le nom de la classe sur la chaîne par réflexion.

 classes = [Person,Child,Parent]
def find_class(name):
 for clls in classes:
  if clls.__class__.__name__ == name:
   return clls
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X