2010-09-05 16 views
82

Gegeben ein Django-Modell, ich versuche, alle seine Felder aufzulisten. Ich habe einige Beispiele dafür gesehen, das mit dem Attribut _meta model zu tun, aber zeigt der Unterstrich vor dem meta nicht an, dass das Attribut _meta ein privates Attribut ist und nicht direkt darauf zugegriffen werden sollte? ... Weil sich zum Beispiel das Layout von _meta in Zukunft ändern könnte und keine stabile API sein würde?Hole die Felder des Modells in Django

Ist _meta eine Ausnahme von dieser Regel? Ist es stabil und einsatzbereit oder gilt es als schlecht, darauf zuzugreifen? Oder gibt es eine Funktion oder eine andere Möglichkeit, die Felder eines Modells zu untersuchen, ohne das _meta-Attribut zu verwenden? Unten ist eine Liste einiger Links, die zeigen, wie man dies mit dem Attribut _meta macht

Jeder Rat wird sehr geschätzt.

django object get/set field

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

How to introspect django model fields?

+0

möglich Duplikat starten [Django: Get Liste der Modellfelder?] (Http: // Stackoverflow .com/questions/3106295/django-get-list-of-model-felder) – Anto

Antwort

113

_meta ist privat, aber es ist relativ stabil. Es gibt Bemühungen, es zu formalisieren, zu dokumentieren und den Unterstrich zu entfernen, der vor 1.3 oder 1.4 passieren könnte. Ich kann mir vorstellen, dass Anstrengungen unternommen werden, um sicherzustellen, dass die Dinge rückwärtskompatibel sind, weil viele Leute es ohnehin schon benutzt haben.

Wenn Sie besonders an Kompatibilität interessiert sind, schreiben Sie eine Funktion, die ein Modell übernimmt und die Felder zurückgibt. Das bedeutet, wenn sich etwas in der Zukunft ändert, müssen Sie nur eine Funktion ändern.

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

Ich glaube, das eine Liste der Field Objekte angezeigt werden können. Verwenden Sie getattr(instance, field.name), um den Wert jedes Felds aus der Instanz abzurufen.

Update: Django-Mitwirkende arbeiten an einer API, um das _Meta-Objekt als Teil eines Google Summer of Code zu ersetzen. Siehe:
- https://groups.google.com/forum/#!topic/django-developers/hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api

+40

Sie sollten sich auch der Tatsache bewusst sein, dass Sie, wenn Sie auch die Viele-zu-Viele-Felder benötigen, auf 'model._meta 'zugreifen müssen. many_to_many'! –

+1

Danke, Will. Gut zu wissen, dass andere Leute auch _meta benutzen. Ich mag die Idee, eine Wrapper-Funktion zu haben. Lazerscience, danke auch. Gut zu wissen, dass es eine nette Methode gibt, die many_to_many Felder zu bekommen. Joe –

+1

def get_model_fields (self): return self._meta.fields verwendet dies, um alle Modellfelder einfach zurückzugeben ... Vielen Dank ... – garmoncheg

8

Das ist etwas, das sich von Django getan wird, wenn ein Formular aus einem Modell zu bauen. Es verwendet das _meta-Attribut, aber wie Bernhard bemerkte, verwendet es sowohl _meta.fields als auch _meta.many_to_many. Mit Blick auf django.forms.models.fields_for_model, ist dies, wie Sie es tun könnte:

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

Die Modellfelder durch _meta enthalten sind, aufgelistet in mehreren Orten als Listen der jeweiligen Feldobjekte. Es kann einfacher sein, mit ihnen als ein Wörterbuch zu arbeiten, wo die Schlüssel die Feldnamen sind.

Meiner Meinung nach ist dies die meist irredundante und ausdruck Weg, um das Modellfeld Objekte zu sammeln und zu organisieren:

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 

(This example usage in django.forms.models.fields_for_model See.

)
+2

Sie möchten vielleicht Ihren Code mit begleiten eine kurze Beschreibung dessen, was es tut. –

+2

----- fertig. ------ – jxqz

58

Ich weiß, dass dieser Beitrag ist ziemlich alt, aber ich sorgte mich nur jemand zu sagen, wer für die gleiche Sache sucht, dass es eine öffentliche und offizielle API ist, dies zu tun: get_fields() und get_field()

Verbrauch:

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

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

+6

Dies ist eigentlich richtige Antwort für neuere Version von Django. – chhantyal

+0

1.10 'get_fields()' https://docs.djangoproject.com/de/1.10/ref/models/meta/#django.db.models.options.Options.get_fields – Risadinha

1

Wie wäre es diese.

fields = Model._meta.fields 
+1

Ich stelle mir vor, dass man vielleicht auf die Eigenschaften von zugreifen möchte ein Feld. Wie bereits in früheren Antworten erwähnt, gibt es 'many_to_many' und' virtual_fields'. – Jocke

+0

@Jocke Recht du bist. Es kann erforderlich sein, auf ein anderes Attribut zuzugreifen.Antwort bearbeitet. – JDE876

2

Jetzt gibt es spezielle Methode - get_fields()

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

Es akzeptiert zwei Parameter, die verwendet werden können, um zu steuern, welche Felder zurückgegeben:

  • include_parents

    Standardmäßig true Umfasst rekursiv Felder, die für übergeordnete Klassen definiert sind. Wenn der Parameter auf False gesetzt ist, sucht get_fields() nur nach Feldern, die direkt im aktuellen Modell deklariert sind. Felder aus Modellen, die direkt von abstrakten Modellen oder Proxyklassen erben, werden als lokal und nicht als übergeordnete Elemente betrachtet.

  • include_hidden

    Falsch standardmäßig. Wenn dieser Wert auf "True" gesetzt ist, enthält get_fields() Felder, die für die Funktionalität anderer Felder verwendet werden. Dazu gehören auch alle Felder, die related_name (wie ManyToManyField oder ForeignKey) haben, die mit einem „+“

Verwandte Themen