Auf die Felder des Django-Modells mit einer Zeichenfolge anstelle einer Punktsyntax zugreifen?

77

In Django kann ich das tun:

test = Test.objects.get(id=1)
test.name

Ich möchte in der Lage sein, mit dynamisch generierten Zeichenfolgen wie folgt auf die Eigenschaften zuzugreifen:

test['name']

oder eine andere Syntax, die eine Zeichenfolge verwendet. Ich habe es versucht

test._meta.get_field_by_name('name')

Dies gibt jedoch das Feld selbst und nicht den Wert zurück.

Irgendwelche Ideen?

Davidcolgan
quelle

Antworten:

111

Sie können die in Python integrierte getattr()Funktion verwenden:

getattr(test, 'name')
Caspar
quelle
2
Eine Minute zu langsam! Hätte mir nicht die Zeit nehmen sollen, es auszuprobieren;)
Caspar
2
Ah, ich musste nicht einmal die Django-Funktionalität verwenden und habe etwas Neues über Python gelernt. Danke für die Hilfe.
Davidcolgan
Arbeitet für ForeignKey?
Giancarlo Ventura
Würde jemand wissen, wie wir dies innerhalb einer internen Klassenmethode für das Modell nennen .... self.getattr(SelfModelName, 'id')= ??
Micheal J. Roberts
Ein bisschen spät, aber Sie können einfach getattr (self, 'id') verwenden
Brouwer
12

Andere Antworten stehen noch, aber jetzt können Sie dies mit Djangos _meta.get_field () tun.

test._meta.get_field('name')

Beachten Sie, dass die Model _meta-API ab 1.8 ihre offizielle Unterstützung und Dokumentation begonnen hat , jedoch vor ihrer offiziellen Dokumentation in früheren Versionen verteilt und verwendet wurde.

Davidhwang
quelle
2
Dies gibt immer noch das Feld selbst zurück, und das OP war am Wert des Feldes interessiert.
Rob3c
6

In Python können Sie normalerweise auf Werte innerhalb eines Objekts zugreifen, das über eine Diktiermethode verfügt .

Angenommen, Sie haben diese Klasse:

class Dog(object):
    def __init___(self, color):
        self.color = color

Und dann instanziiere ich es:

dog = Dog('brown')

So kann ich die Farbe sehen, indem ich:

print dog.color

Ich kann die Farbe auch sehen, indem ich:

print dog.__dict__['color']

Ich kann die Farbe einstellen:

print dog.__dict__['color'] = 'green'

print dog.color

>>>green
James R.
quelle
1
Es wird funktionieren, aber im Allgemeinen möchten Sie die Verwendung unterstrichener Attribute / Methoden nach Möglichkeit vermeiden. Es ist ein Signal dafür, dass sie volatil sind (jederzeit ohne Warnung vollständig gelöscht oder von Natur aus geändert werden können) oder aus einem anderen Grund nicht Teil der öffentlichen Schnittstelle sein sollen. Manchmal muss man, aber in diesem Fall getattrist es verfügbar und daher die richtige Wahl.
Chris Pratt
@ChrisPratt Es gibt einen Unterschied zwischen einfachem Unterstrich, doppeltem Unterstrich und doppeltem Unterstrich mit nachfolgendem doppeltem Unterstrich. Während das, was Sie gesagt haben, (mehr oder weniger) für die beiden ersteren gilt, impliziert die Methode , dass es sich um eine integrierte Methode handelt , die keinerlei Hinweis auf Privatsphäre oder Schutz gibt und wo Sie normalerweise eine Überladung und Initialisierung des Bedieners durchführen. docs.python.org/reference/datamodel.html#specialnames siafoo.net/article/57 stackoverflow.com/questions/1301346/…
ashwoods
1
@ashwoods: stimmt, aber selbst dann ist die Verwendung in der Regel in einer anderen Klasse enthalten, sodass es sich um eine Art internen Code handelt, der die interne Codesituation verwendet. Letztendlich verwenden Sie solche Methoden im Allgemeinen nicht nur in anderen Klassen, die die spezifische Implementierung noch von der "öffentlichen" Schnittstelle fernhalten.
Chris Pratt
@ChrisPratt, das ist an dieser Stelle alles ziemlich akademisch, aber wenn Sie kurz auf Seite 84 von Python verweisen, beschreibt er dieses Verhalten in der zweiten Ausgabe. Er sagt: "Es gibt keinen Unterschied zwischen Klassenattributen, die im Klassenkörper, außerhalb des Körpers durch Zuweisen eines Attributs oder außerhalb des Körpers durch explizites Binden eines Eintrags in C .__ dict__ erstellt wurden. Trotzdem stimme ich zu, dass getattr wahrscheinlich das Richtige ist Lösung unter diesen Umständen, aber das bedeutet nicht, dass man das Diktat außerhalb des Klassenkörpers oder eine andere Methode mit doppeltem Unterstrich nicht verwenden kann
James R,