Dado un modelo de Django, estoy tratando de enumerar todos sus campos. He visto algunos ejemplos de cómo hacer esto usando el atributo del modelo _meta, pero ¿no indica el guión bajo delante del meta que el atributo _meta es 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 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 hacer esto usando el atributo _meta
Cualquier consejo es muy apreciado.
campo get / set del objeto django
Respuestas:
_meta
es privado, pero relativamente estable. Hay esfuerzos para formalizarlo, documentarlo y eliminar el subrayado, lo que podría suceder antes de 1.3 o 1.4. Me imagino que se hará un esfuerzo para asegurar 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.
Creo que esto devolverá una lista de
Field
objetos. Para obtener el valor de cada campo de la instancia, usegetattr(instance, field.name)
.Actualización: los colaboradores de Django están trabajando en una API para reemplazar el objeto _Meta como parte de Google Summer of Code. Ver:
- https://groups.google.com/forum/#!topic/django-developers/hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api
fuente
model._meta.many_to_many
.django/core/management/commands/loaddata.py
usa _meta para recorrer el árbol de aplicaciones, modelos y campos. Buen patrón a seguir ... y puedes apostar que es la "forma oficial"._meta.virtual_fields
_meta
ahora es una API formal y compatible (nuevo en Django 1.8)Sé que esta publicación es bastante antigua, pero solo quería decirle a cualquiera que esté buscando lo mismo que hay una API pública y oficial para hacer esto:
get_fields()
yget_field()
Uso:
https://docs.djangoproject.com/en/1.8/ref/models/meta/
fuente
get_fields()
docs.djangoproject.com/en/1.10/ref/models/meta/…_meta
?Ahora hay un método especial: get_fields ()
Acepta dos parámetros que se pueden usar para controlar qué campos se devuelven:
include_parents
Verdadero por defecto. Incluye de forma recursiva campos definidos en clases principales. Si se establece en False, get_fields () solo buscará 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 del padre.
include_hidden
Falso por defecto. Si se establece en True, get_fields () incluirá campos que se utilizan para respaldar la funcionalidad de otros campos. Esto también incluirá cualquier campo que tenga un related_name (como ManyToManyField o ForeignKey) que comience con un "+"
fuente
get_fields()
devuelve untuple
y cada elemento es unModel field
tipo, que no se puede usar directamente como una cadena. Entonces,field.name
devolverá el nombre del campomy_model_fields = [field.name for field in MyModel._meta.get_fields()]
El código anterior devolverá una lista con todos los campos de nombre
Ejemplo
fuente
Esto es algo que hace Django al construir un formulario a partir de un modelo. Está usando el atributo _meta, pero como señaló Bernhard, usa tanto _meta.fields como _meta.many_to_many. Mirando django.forms.models.fields_for_model, así es como podría hacerlo:
fuente
Los campos de modelo contenidos por _meta se enumeran en varias ubicaciones como listas de los respectivos objetos de campo. 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 forma más irredundante y expresiva de recopilar y organizar los objetos de campo del modelo:
(Consulte Este ejemplo de uso en django.forms.models.fields_for_model).
fuente
Que tal este.
fuente
many_to_many
yvirtual_fields
.Según la documentación de django 2.2, puede usar:
Para obtener todos los campos:
Model._meta.get_fields()
Para obtener un campo individual:
Model._meta.get_field('field name')
ex.
Session._meta.get_field('expire_date')
fuente
Si necesita esto para su sitio de administración , también existe el
ModelAdmin.get_fields
método ( docs ), que devuelve unlist
nombre de campostrings
.Por ejemplo:
fuente
Otra forma es agregar funciones al modelo y cuando desee anular la fecha, puede llamar a la función.
fuente