Bei einem Django-Modell versuche ich, alle seine Felder aufzulisten. Ich habe einige Beispiele dafür mit dem _meta-Modellattribut gesehen, aber zeigt der Unterstrich vor dem Meta nicht an, dass das _meta-Attribut ein privates Attribut ist und nicht direkt aufgerufen werden sollte? ... weil sich beispielsweise das Layout von _meta in Zukunft ändern könnte und keine stabile API sein könnte?
Ist _meta eine Ausnahme von dieser Regel? Ist es stabil und gebrauchsfertig oder wird es als schlechte Praxis angesehen, darauf zuzugreifen? Oder gibt es eine Funktion oder eine andere Möglichkeit, die Felder eines Modells ohne Verwendung des Attributs _meta zu überprüfen? Unten finden Sie eine Liste einiger Links, die zeigen, wie dies mit dem Attribut _meta durchgeführt wird
Jeder Rat wird sehr geschätzt.
Antworten:
_meta
ist privat, aber es ist relativ stabil. Es wird versucht, es zu formalisieren, zu dokumentieren und den Unterstrich zu entfernen, was vor 1.3 oder 1.4 geschehen kann. Ich kann mir vorstellen, dass Anstrengungen unternommen werden, um sicherzustellen, dass die Dinge abwärtskompatibel sind, da viele Leute sie sowieso benutzt haben.Wenn Sie besonders über die Kompatibilität besorgt sind, schreiben Sie eine Funktion, die ein Modell verwendet und die Felder zurückgibt. Das heißt, wenn sich in Zukunft etwas ändert, müssen Sie nur eine Funktion ändern.
Ich glaube, dies wird eine Liste von
Field
Objekten zurückgeben. Verwenden Sie, um den Wert jedes Felds aus der Instanz abzurufengetattr(instance, field.name)
.Update: Django-Mitarbeiter 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
quelle
model._meta.many_to_many
!django/core/management/commands/loaddata.py
verwendet _meta, um den Baum von Apps, Modellen und Feldern zu durchsuchen. Schönes Muster zu folgen ... und Sie können wetten, es ist der "offizielle Weg"._meta.virtual_fields
_meta
ist jetzt eine formale, unterstützte API (neu in Django 1.8)Ich weiß, dass dieser Beitrag ziemlich alt ist, aber ich wollte nur jedem, der nach dem gleichen Thema sucht, mitteilen, dass es eine öffentliche und offizielle API gibt, um dies zu tun:
get_fields()
undget_field()
Verwendung:
https://docs.djangoproject.com/de/1.8/ref/models/meta/
quelle
get_fields()
docs.djangoproject.com/de/1.10/ref/models/meta/…_meta
?Jetzt gibt es eine spezielle Methode - get_fields ()
Es werden zwei Parameter akzeptiert, mit denen gesteuert werden kann, welche Felder zurückgegeben werden:
include_parents
Standardmäßig True. Enthält rekursiv Felder, die für übergeordnete Klassen definiert sind. Bei der Einstellung False sucht get_fields () nur nach Feldern, die direkt im aktuellen Modell deklariert sind. Felder von Modellen, die direkt von abstrakten Modellen oder Proxy-Klassen erben, gelten als lokal und nicht auf dem übergeordneten Modell.
include_hidden
Standardmäßig falsch. Wenn auf True gesetzt, enthält get_fields () Felder, mit denen die Funktionalität anderer Felder unterstützt wird. Dies schließt auch alle Felder mit einem verwandten Namen ein (z. B. ManyToManyField oder ForeignKey), die mit einem „+“ beginnen.
quelle
get_fields()
gibt a zurücktuple
und jedes Element ist einModel field
Typ, der nicht direkt als Zeichenfolge verwendet werden kann. Gibt alsofield.name
den Feldnamen zurückmy_model_fields = [field.name for field in MyModel._meta.get_fields()]
Der obige Code gibt eine Liste zurück, die alle Feldnamen enthält.
Beispiel
quelle
Dies wird von Django selbst durchgeführt, wenn ein Formular aus einem Modell erstellt wird. Es verwendet das Attribut _meta, aber wie Bernhard bemerkte, verwendet es sowohl _meta.fields als auch _meta.many_to_many. Wenn Sie sich django.forms.models.fields_for_model ansehen, können Sie dies folgendermaßen tun:
quelle
Die in _meta enthaltenen Modellfelder werden an mehreren Stellen als Listen der jeweiligen Feldobjekte aufgelistet. Es kann einfacher sein, mit ihnen als Wörterbuch zu arbeiten, wobei die Schlüssel die Feldnamen sind.
Meiner Meinung nach ist dies die irredundanteste und ausdrucksstärkste Art, die Modellfeldobjekte zu sammeln und zu organisieren:
(Siehe Verwendung dieses Beispiels in django.forms.models.fields_for_model.)
quelle
Wie wäre es mit diesem.
quelle
many_to_many
undvirtual_fields
.Gemäß der Django-Dokumentation 2.2 können Sie Folgendes verwenden:
So erhalten Sie alle Felder:
Model._meta.get_fields()
So erhalten Sie ein individuelles Feld:
Model._meta.get_field('field name')
Ex.
Session._meta.get_field('expire_date')
quelle
Wenn Sie dies für Ihre Admin- Site benötigen , gibt es auch die
ModelAdmin.get_fields
Methode ( docs ), die einenlist
Feldnamen zurückgibtstrings
.Beispielsweise:
quelle
Eine andere Möglichkeit besteht darin, dem Modell Funktionen hinzuzufügen. Wenn Sie das Datum überschreiben möchten, können Sie die Funktion aufrufen.
quelle