Ich habe eine User
Klasse definiert , von der (letztendlich) geerbt wird models.Model
. Ich möchte eine Liste aller für dieses Modell definierten Felder erhalten. Zum Beispiel phone_number = CharField(max_length=20)
. Grundsätzlich möchte ich alles abrufen, was von der Field
Klasse erbt .
Ich dachte, ich könnte diese abrufen, indem ich sie ausnütze inspect.getmembers(model)
, aber die zurückgegebene Liste enthält keines dieser Felder. Es sieht so aus, als hätte Django die Klasse bereits in den Griff bekommen und all ihre magischen Attribute hinzugefügt und herausgenommen, was tatsächlich definiert wurde. Also ... wie kann ich diese Felder bekommen? Sie haben wahrscheinlich eine Funktion, um sie für ihre eigenen internen Zwecke abzurufen?
django
django-models
mpen
quelle
quelle
Antworten:
Da die meisten Antworten veraltet sind, werde ich versuchen, Sie auf Django 2.2 zu aktualisieren. Hier Beiträge - Ihre App (Beiträge, Blog, Shop usw.)
1) Vom Modelllink : https://docs.djangoproject.com/de/2.2/ref/models/meta/
Beachten Sie, dass:
Wird auch einige Beziehungen bekommen, die zum Beispiel. Sie können nicht in einer Ansicht anzeigen.
Wie in meinem Fall:
und
2) Von der Instanz
3) Vom übergeordneten Modell
Nehmen wir an, wir haben Post als übergeordnetes Modell und Sie möchten, dass alle Felder in einer Liste angezeigt werden und die Felder der übergeordneten Felder im Bearbeitungsmodus schreibgeschützt sind.
quelle
clean_field_names = [str(h).split('.')[2].replace("_", " ").title() for h in all_fields]
all_fields = bp._meta.fields
Django-Versionen 1.8 und höher:
Sie sollten verwenden
get_fields()
:Die
get_all_field_names()
Methode ist ab Django 1.8 veraltet und wird in 1.10 entfernt .Die oben verlinkte Dokumentationsseite bietet eine vollständig abwärtskompatible Implementierung von
get_all_field_names()
, aber für die meisten Zwecke sollte das vorherige Beispiel einwandfrei funktionieren.Django-Versionen vor 1.8:
Das sollte den Trick machen.
Das erfordert eine tatsächliche Modellinstanz. Wenn Sie nur eine Unterklasse von haben
django.db.models.Model
, sollten Sie anrufenmyproject.myapp.models.MyModel._meta.get_all_field_names()
quelle
model._meta.fields
, und ihre Namen sind damit abrufbarfield.name
. Ich hoffe nur, dass dies der stabilste Weg ist, um diese Informationen abzurufen :)django.db.models.Model
. Ich werde mich damit_meta
Attribut zu tun , ist der einzige Weg ..._meta.many_to_many
Suchen Sie zusätzlich nach ManyToMany-Feldern!Die
get_all_related_fields()
hier erwähnte Methode ist in 1.8 veraltet . Von jetzt an ist esget_fields()
.quelle
Ich finde es sehr hilfreich, dies zu Django-Modellen hinzuzufügen:
So können Sie:
quelle
django.db.models.fields.related.RelatedObjectDoesNotExist: CustomModel has no custom_attribute.
ForeignKey
Arbeit gut für mich. Das stille Fangen aller Ausnahmen ist jedoch ein Anti-Muster. Viel besser zu fangenAttributeError
oder zumindest zu protokollieren, dass eine Ausnahme lautlos verschluckt wurde.self._meta.get_all_field_names()
wurde abgeschrieben und entfernt. Sie können so etwas wiefor field in self._meta.get_fields()
und dannyield (field.name, field.value_from_object(self))
Das macht den Trick. Ich teste es nur in Django 1.7.
Model._meta.local_fields
enthält keine Viele-zu-Viele-Felder. Sie sollten sie mit bekommenModel._meta.local_many_to_many
.quelle
Es ist nicht klar, ob Sie eine Instanz der Klasse oder der Klasse selbst haben und versuchen, die Felder abzurufen, aber in beiden Fällen sollten Sie den folgenden Code berücksichtigen
Verwenden einer Instanz
Eine Klasse benutzen
quelle
Das hat bei mir funktioniert
django==1.11.8
quelle
MyModel._meta.get_all_field_names()
wurde als veraltet mehrere Versionen zurück und entfernt in Django 1.10.Hier ist der abwärtskompatible Vorschlag aus den Dokumenten :
quelle
Nur um hinzuzufügen, ich benutze Selbstobjekt, das hat bei mir funktioniert:
quelle
Beachten Sie zumindest bei Django 1.9.9 - der Version, die ich derzeit verwende -, dass
.get_fields()
tatsächlich auch jedes fremde Modell als Feld "betrachtet" wird, was problematisch sein kann. Angenommen, Sie haben:Es folgt dem
während, wie von @Rockallite gezeigt
quelle
Bevor ich diesen Beitrag gefunden habe, habe ich erfolgreich festgestellt, dass er funktioniert.
Es funktioniert genauso wie
Ich bin mir nicht sicher, was der Unterschied in den Ergebnissen ist, wenn es einen gibt. Ich habe diese Schleife ausgeführt und die gleiche Ausgabe erhalten.
quelle
Warum nicht einfach das benutzen:
Beispielausgabe:
quelle