name _meta django django-models

_meta - Django: ¿Obtener lista de campos modelo?



django model_meta (9)

Al menos con Django 1.9.9 , la versión que estoy usando actualmente, tenga en cuenta que .get_fields() realidad también "considera" cualquier modelo extranjero como un campo, lo que puede ser problemático. Digamos que tienes:

class Parent(models.Model): id = UUIDField(primary_key=True) class Child(models.Model): parent = models.ForeignKey(Parent)

Resulta que

>>> map(lambda field:field.name, Parent._model._meta.get_fields()) [''id'', ''child'']

mientras que, como se muestra por @Rockallite

>>> map(lambda field:field.name, Parent._model._meta.local_fields) [''id'']

models.Model una clase de User que (en última instancia) hereda de models.Model . Quiero obtener una lista de todos los campos definidos para este modelo. Por ejemplo, phone_number = CharField(max_length=20) . Básicamente, quiero recuperar todo lo que herede de la clase Field .

Pensé que podría recuperarlos aprovechando inspect.getmembers(model) , pero la lista que devuelve no contiene ninguno de estos campos. Parece que Django ya se ha hecho con la clase y ha agregado todos sus atributos mágicos y ha eliminado lo que realmente se ha definido. Entonces ... ¿cómo puedo obtener estos campos? Probablemente tienen una función para recuperarlos para sus propios fines internos?


El método get_all_related_fields() mencionado en este documento ha quedado obsoleto en 1.8 . A partir de ahora es get_fields() .

>> from django.contrib.auth.models import User >> User._meta.get_fields()


Esto hace el truco. Solo lo pruebo en Django 1.7.

your_fields = YourModel._meta.local_fields your_field_names = [f.name for f in your_fields]

Model._meta.local_fields no contiene muchos campos. Debería obtenerlos usando Model._meta.local_many_to_many .


Me parece muy útil agregar esto a los modelos django:

def __iter__(self): for field_name in self._meta.get_all_field_names(): value = getattr(self, field_name, None) yield (field_name, value)

Esto te permite:

for field, val in object: print field, val


No está claro si tiene una instancia de la clase o la clase en sí e intenta recuperar los campos, pero de cualquier forma, tenga en cuenta el siguiente código

Usando una instancia

instance = User.objects.get(username="foo") instance.__dict__ # returns a dictionary with all fields and their values instance.__dict__.keys() # returns a dictionary with all fields list(instance.__dict__.keys()) # returns list with all fields

Usando una clase

User._meta.__dict__.get("fields") # returns the fields # to get the field names consider looping over the fields and calling __str__() for field in User._meta.__dict__.get("fields"): field.__str__() # e.g. ''auth.User.id''


Para las versiones 1.8 y posteriores de Django:

El método get_all_field_names() está en desuso a partir de Django 1.8 y se eliminará en 1.10 .

La página de documentación vinculada anteriormente proporciona una implementación completamente compatible con versiones anteriores de get_all_field_names() , pero para la mayoría de los propósitos [f.name for f in MyModel._meta.get_fields()] debería funcionar bien.

Para las versiones de Django anteriores a la 1.8:

model._meta.get_all_field_names()

Eso debería hacer el truco.

Eso requiere una instancia de modelo real. Si todo lo que tiene es una subclase de django.db.models.Model , debe llamar a myproject.myapp.models.MyModel._meta.get_all_field_names()


Solo para agregar, estoy usando autoobjeto, esto funcionó para mí:

[f.name for f in self.model._meta.get_fields()]


MyModel._meta.get_all_field_names() se MyModel._meta.get_all_field_names() varias versiones y se eliminó en Django 1.10.

Aquí está la sugerencia compatible con versiones anteriores de los documentos :

from itertools import chain list(set(chain.from_iterable( (field.name, field.attname) if hasattr(field, ''attname'') else (field.name,) for field in MyModel._meta.get_fields() # For complete backwards compatibility, you may want to exclude # GenericForeignKey from the results. if not (field.many_to_one and field.related_model is None) )))


def __iter__(self): field_names = [f.name for f in self._meta.fields] for field_name in field_names: value = getattr(self, field_name, None) yield (field_name, value)

Esto funcionó para mí en django==1.11.8