Ottieni i campi del modello in Django

Dato un modello Django, sto cercando di elencare tutti i suoi campi. Ho visto alcuni esempi di fare ciò usando l’attributo _meta model, ma il carattere di sottolineatura davanti al meta indica che l’attributo _meta è un attributo privato e non dovrebbe essere accessibile direttamente? … Perché, ad esempio, il layout di _meta potrebbe cambiare in futuro e non essere un’API stabile?

_Meta è un’eccezione a questa regola? È stabile e pronto per l’uso o è considerato una ctriggers pratica accedervi? O c’è una funzione o qualche altro modo per introspezionare i campi di un modello senza usare l’attributo _meta? Di seguito è riportato un elenco di alcuni collegamenti che mostrano come eseguire l’operazione utilizzando l’attributo _meta

Ogni consiglio è molto apprezzato.

campo get / set dell’object django

http://www.djangofoo.com/80/get-list-model-fields

Come introspezionare i campi del modello di django?

_meta è privato, ma è relativamente stabile. Ci sono sforzi per formalizzarlo, documentarlo e rimuovere il carattere di sottolineatura, che potrebbe accadere prima di 1.3 o 1.4. Immagino che sarà fatto uno sforzo per garantire che le cose siano compatibili all’indietro, perché molte persone lo hanno comunque utilizzato.

Se sei particolarmente interessato alla compatibilità, scrivi una funzione che accetta un modello e restituisce i campi. Questo significa che se qualcosa cambia in futuro, devi solo cambiare una funzione.

 def get_model_fields(model): return model._meta.fields 

Credo che questo restituirà una lista di oggetti Field . Per ottenere il valore di ogni campo getattr(instance, field.name) , utilizzare getattr(instance, field.name) .

Aggiornamento: i contributori di Django stanno lavorando su un’API per sostituire l’object _Meta come parte di un Google Summer of Code. Vedere:
https://groups.google.com/forum/#!topic/django-developers/hD4roZq0wyk
https://code.djangoproject.com/wiki/new_meta_api

So che questo post è piuttosto vecchio, ma mi interessa solo dire a chiunque stia cercando la stessa cosa che c’è un’API pubblica e ufficiale per farlo: get_fields() e get_field()

Uso:

 fields = model._meta.get_fields() my_field = model._meta.get_field('my_field') 

https://docs.djangoproject.com/en/1.8/ref/models/meta/

Questo è qualcosa che viene fatto da Django stesso quando si costruisce un modulo da un modello. Sta usando l’attributo _meta, ma come notato da Bernhard, usa sia _meta.fields che _meta.many_to_many. Guardando django.forms.models.fields_for_model, ecco come si potrebbe fare:

 opts = model._meta for f in sorted(opts.fields + opts.many_to_many): print '%s: %s' % (f.name, f) 

I campi del modello contenuti da _meta sono elencati in più posizioni come elenchi dei rispettivi oggetti di campo. Potrebbe essere più semplice lavorare con loro come dizionario in cui le chiavi sono i nomi dei campi.

Secondo me, questo è il modo più irredente ed espressivo per raccogliere e organizzare gli oggetti del campo del modello:

 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 

(Vedi questo esempio di utilizzo in django.forms.models.fields_for_model.)

Ora c’è un metodo speciale – get_fields ()

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

Accetta due parametri che possono essere utilizzati per controllare quali campi vengono restituiti:

  • include_parents

    True per impostazione predefinita. Include in modo ricorsivo i campi definiti sulle classi parent. Se impostato su False, get_fields () cercherà solo i campi dichiarati direttamente sul modello corrente. I campi dei modelli che ereditano direttamente da modelli astratti o classi proxy sono considerati locali, non sul genitore.

  • include_hidden

    Falso per impostazione predefinita. Se impostato su True, get_fields () includerà i campi utilizzati per supportare la funzionalità di altri campi. Ciò includerà anche tutti i campi che hanno un related_name (come ManyToManyField o ForeignKey) che iniziano con un “+”

get_fields() restituisce una tuple e ogni elemento è un tipo di Model field , che non può essere usato direttamente come una stringa. Quindi, field.name restituirà il nome del campo

my_model_fields = [field.name for field in MyModel._meta.get_fields()]
Il codice sopra riportato restituirà una lista con il nome di tutti i campi

Esempio

 In [11]: from django.contrib.auth.models import User In [12]: User._meta.get_fields() Out[12]: (, , , , , , , , , , , , , ) In [13]: [field.name for field in User._meta.get_fields()] Out[13]: ['logentry', 'id', 'password', 'last_login', 'is_superuser', 'username', 'first_name', 'last_name', 'email', 'is_staff', 'is_active', 'date_joined', 'groups', 'user_permissions'] 

Che ne dici di questo.

 fields = Model._meta.fields