all - Obtener los campos del modelo en Django
get all attributes model django (6)
Dado un modelo de Django, estoy tratando de enumerar todos sus campos. He visto algunos ejemplos de hacer esto usando el atributo de modelo _meta, pero ¿el guión bajo al frente de la meta no indica que el atributo _meta sea un atributo privado y no se debe acceder directamente? ... Porque, por ejemplo, ¿el diseño de _meta podría cambiar en el futuro y no ser una API estable?
¿_meta es una excepción a esta regla? ¿Es estable y está listo para usar o se considera una mala práctica para acceder a él? ¿O hay una función o alguna otra forma de introspectar los campos de un modelo sin usar el atributo _meta? A continuación se muestra una lista de algunos enlaces que muestran cómo hacerlo utilizando el atributo _meta
Cualquier consejo es muy apreciado.
Ahora hay un método especial - get_fields()
>>> from django.contrib.auth.models import User
>>> User._meta.get_fields()
Acepta dos parámetros que se pueden usar para controlar qué campos se devuelven:
include_parents
Verdadero por defecto. Recursivamente incluye campos definidos en clases principales. Si se establece en False, get_fields () solo buscará los campos declarados directamente en el modelo actual. Los campos de modelos que heredan directamente de modelos abstractos o clases de proxy se consideran locales, no en el principal.
include_hidden
Falso por defecto. Si se establece en True, get_fields () incluirá los campos que se utilizan para respaldar la funcionalidad de otros campos. Esto también incluirá cualquier campo que tenga un nombre relacionado (como ManyToManyField o ForeignKey) que comience con un "+"
Esto es algo que hace Django cuando construye un formulario a partir de un modelo. Está utilizando el atributo _meta, pero como notó Bernhard, usa tanto _meta.fields como _meta.many_to_many. Mirando django.forms.models.fields_for_model, así es como podrías hacerlo:
opts = model._meta
for f in sorted(opts.fields + opts.many_to_many):
print ''%s: %s'' % (f.name, f)
Los campos de modelo que contiene _meta se enumeran en varias ubicaciones como listas de los objetos de campo respectivos. Puede ser más fácil trabajar con ellos como un diccionario donde las claves son los nombres de los campos.
En mi opinión, esta es la manera más irreductiva y expresiva de recopilar y organizar los objetos de campo modelo:
def get_model_fields(model):
fields = {}
options = model._meta
for field in sorted(options.concrete_fields + options.many_to_many + options.virtual_fields):
fields[field.name] = field
return fields
(Consulte este uso de ejemplo en django.forms.models.fields_for_model).
Que tal este.
fields = Model._meta.fields
Sé que esta publicación es bastante antigua, pero me importa decirle a cualquiera que esté buscando lo mismo que hay una API pública y oficial que haga esto: get_fields()
y get_field()
Uso:
fields = model._meta.get_fields()
my_field = model._meta.get_field(''my_field'')
_meta
es privado, pero es relativamente estable. Hay esfuerzos para formalizarlo, documentarlo y eliminar el guión bajo, que podría ocurrir antes de 1.3 o 1.4. Imagino que se hará un esfuerzo para garantizar que las cosas sean compatibles con versiones anteriores, porque mucha gente lo ha estado usando de todos modos.
Si está particularmente preocupado por la compatibilidad, escriba una función que tome un modelo y devuelva los campos. Esto significa que si algo cambia en el futuro, solo tiene que cambiar una función.
def get_model_fields(model):
return model._meta.fields
Creo que esto devolverá una lista de objetos Field
. Para obtener el valor de cada campo de la instancia, use getattr(instance, field.name)
.
Actualización: los colaboradores de Django están trabajando en una API para reemplazar el objeto _Meta como parte de un Google Summer of Code. Ver:
- https://groups.google.com/forum/#!topic/django-developers/hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api