Erhalte die Modellfelder in Django

Bei einem Django-Modell versuche ich alle 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?

Ist _meta eine Ausnahme von dieser Regel? Ist es stabil und einsatzbereit oder gilt es als schlecht, darauf zuzugreifen? Oder gibt es eine function oder eine andere Möglichkeit, die Felder eines Modells zu untersuchen, ohne das _meta-Attribut zu verwenden? Im Folgenden finden Sie eine Liste einiger Links, die zeigen, wie Sie dies mit dem _meta-Attribut tun können

Jeder Rat wird sehr geschätzt.

Django-Objekt get / set-Feld

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

Wie man Django-Modellfelder inspiziert?

   

    _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 function, die ein Modell übernimmt und die Felder zurückgibt. Das bedeutet, wenn sich etwas in der Zukunft ändert, müssen Sie nur eine function ändern.

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

    Ich glaube, das wird eine Liste von Field Objekten zurückgeben. Verwenden Sie getattr(instance, field.name) um den Wert jedes Felds aus der Instanz getattr(instance, field.name) .

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

    Ich weiß, dass dieser Beitrag ziemlich alt ist, aber ich wollte nur jedem, der nach dem gleichen sucht, sagen, dass es eine öffentliche und offizielle API dafür gibt: get_fields() und get_field()

    Verwendung:

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

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

    Dies wird von Django selbst gemacht, wenn ein Formular aus einem Modell erstellt wird. Es verwendet das _meta-Attribut, aber wie Bernhard bemerkte, verwendet es sowohl _meta.fields als auch _meta.many_to_many. Wenn Sie django.forms.models.fields_for_model betrachten, können Sie Folgendes tun:

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

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

    Meiner Meinung nach ist dies der einfachste und expressivste Weg, die Modellfeldobjekte 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 

    (Siehe Dieses Beispiel in django.forms.models.fields_for_model.)

    Jetzt gibt es spezielle Methode – get_fields ()

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

    Es akzeptiert zwei Parameter, mit denen gesteuert werden kann, welche Felder zurückgegeben werden:

    • include_parents

      Standardmäßig true Umfasst rekursiv Felder, die für übergeordnete classn 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

      Standardmäßig falsch. Wenn dieser Wert auf “True” gesetzt ist, enthält get_fields () Felder, die für die functionalität anderer Felder verwendet werden. Dies schließt auch alle Felder mit einem verwandten Namen ein (z. B. ManyToManyField oder ForeignKey), die mit einem “+” beginnen.

    get_fields() gibt ein tuple und jedes Element ist ein get_fields() , der nicht direkt als String verwendet werden kann. Also wird field.name den Feldnamen zurückgeben

    my_model_fields = [field.name for field in MyModel._meta.get_fields()]
    Der obige Code gibt eine Liste mit allen Feldern zurück

    Beispiel

     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'] 

    Wie wäre es mit diesem.

     fields = Model._meta.fields