Étant donné un modèle Django, j'essaye de lister tous ses champs. J'ai vu quelques exemples de faire cela en utilisant l'attribut de modèle _meta, mais le trait de soulignement devant meta n'indique-t-il pas que l'attribut _meta est un attribut privé et ne doit pas être accédé directement? ... Parce que, par exemple, la mise en page de _meta pourrait changer dans le futur et ne pas être une API stable?
_Meta est-il une exception à cette règle? Est-il stable et prêt à l'emploi ou est-il considéré comme une mauvaise pratique d'y accéder? Ou existe-t-il une fonction ou une autre manière d'introspecter les champs d'un modèle sans utiliser l'attribut _meta? Vous trouverez ci-dessous une liste de quelques liens montrant comment procéder à l'aide de l'attribut _meta
Tout conseil est fort apprécié.
Champ d'objet django get / set
Réponses:
_meta
est privé, mais il est relativement stable. Il y a des efforts pour le formaliser, le documenter et supprimer le trait de soulignement, ce qui peut arriver avant la 1.3 ou la 1.4. J'imagine que des efforts seront faits pour s'assurer que les choses sont rétrocompatibles, car beaucoup de gens l'utilisent de toute façon.Si vous êtes particulièrement préoccupé par la compatibilité, écrivez une fonction qui prend un modèle et renvoie les champs. Cela signifie que si quelque chose change à l'avenir, vous ne devez changer qu'une seule fonction.
Je crois que cela renverra une liste d'
Field
objets. Pour obtenir la valeur de chaque champ à partir de l'instance, utilisezgetattr(instance, field.name)
.Mise à jour: les contributeurs de Django travaillent sur une API pour remplacer l'objet _Meta dans le cadre d'un Google Summer of Code. Voir:
- https://groups.google.com/forum/#!topic/django-developers/hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api
la source
model._meta.many_to_many
!django/core/management/commands/loaddata.py
utilise _meta pour parcourir l'arborescence des applications, des modèles et des champs. Joli schéma à suivre ... et vous pouvez parier que c'est la "voie officielle"._meta.virtual_fields
_meta
est maintenant une API formelle et prise en charge (nouveau dans Django 1.8)Je sais que cet article est assez ancien, mais je voulais juste dire à quiconque cherche la même chose qu'il existe une API publique et officielle pour le faire:
get_fields()
etget_field()
Usage:
https://docs.djangoproject.com/en/1.8/ref/models/meta/
la source
get_fields()
docs.djangoproject.com/en/1.10/ref/models/meta/…_meta
?Maintenant, il existe une méthode spéciale - get_fields ()
Il accepte deux paramètres qui peuvent être utilisés pour contrôler les champs renvoyés:
include_parents
Vrai par défaut. Inclut de manière récursive les champs définis sur les classes parentes. S'il est défini sur False, get_fields () ne recherchera que les champs déclarés directement sur le modèle courant. Les champs des modèles qui héritent directement de modèles abstraits ou de classes proxy sont considérés comme locaux et non sur le parent.
include_hidden
False par défaut. S'il est défini sur True, get_fields () inclura des champs qui sont utilisés pour soutenir les fonctionnalités d'autres champs. Cela inclura également tous les champs qui ont un nom_relié (tel que ManyToManyField ou ForeignKey) commençant par un «+»
la source
get_fields()
renvoie atuple
et chaque élément est unModel field
type, qui ne peut pas être utilisé directement comme chaîne. Donc,field.name
retournera le nom du champmy_model_fields = [field.name for field in MyModel._meta.get_fields()]
Le code ci-dessus renverra une liste contenant tous les noms de champs
Exemple
la source
C'est quelque chose qui est fait par Django lui-même lors de la construction d'un formulaire à partir d'un modèle. Il utilise l'attribut _meta, mais comme Bernhard l'a noté, il utilise à la fois _meta.fields et _meta.many_to_many. En regardant django.forms.models.fields_for_model, voici comment vous pourriez le faire:
la source
Les champs de modèle contenus par _meta sont répertoriés à plusieurs emplacements sous forme de listes des objets de champ respectifs. Il peut être plus facile de travailler avec eux comme un dictionnaire où les clés sont les noms de champ.
À mon avis, c'est la manière la plus irrédondante et la plus expressive de collecter et d'organiser les objets de champ modèle:
(Voir cet exemple d'utilisation dans django.forms.models.fields_for_model.)
la source
Celui-ci, ça va.
la source
many_to_many
etvirtual_fields
.Selon la documentation de django 2.2, vous pouvez utiliser:
Pour obtenir tous les champs:
Model._meta.get_fields()
Pour obtenir un champ individuel:
Model._meta.get_field('field name')
ex.
Session._meta.get_field('expire_date')
la source
Si vous en avez besoin pour votre site d' administration , il existe également la
ModelAdmin.get_fields
méthode ( docs ), qui renvoie unlist
nom de champstrings
.Par exemple:
la source
Une autre méthode consiste à ajouter des fonctions au modèle et lorsque vous souhaitez remplacer la date, vous pouvez appeler la fonction.
la source