Getter für properties von Django Models?

Django, Flask, Bottle, WSGI, CGI…
Antworten
skirnir
User
Beiträge: 36
Registriert: Sonntag 25. Januar 2015, 10:59

Hallo,

Es könnte sein, daß mein Problem eher in "Allgemeine Fragen" gehört. Da meine "Problemklassen" aber Django Models sind, habe ich mich entschieden es hier zu posten.
Ich bin gerade dabei, ein Django Projekt auf Django 3.x zu upgraden. Die existierende Applikation wurde in Python 2 geschrieben. Meine aktuelle Baustelle sind Models, die so etwas enthalten:

Code: Alles auswählen

bla = models.FloatField('Beschreibung', null=True)
Später gibt es dann solche Checks:

Code: Alles auswählen

if self.bla > 0:
   # do something
Das funktioniert unter Python 2 wie erwartet, Python 3 liefert an der Stelle einen TypeError, wenn self.bla den Wert None hat.
Da die Datenbank noch von anderen Instanzen der Applikation benutzt wird, kann ich nicht einfach 'null=False' setzen und den Datenbestand verändern, ohne weitere Probleme zu riskieren.

Es wäre schön, wenn es eine Möglichkeit gäbe, da einen Getter zu schreiben, der so aussieht:

Code: Alles auswählen

def get_bla(self):
    if self.bla is None:
        return 0
    return self.bla
und der beim Aufruf von 'self.bla' benutzt wird.

Meine bisherigen Recherchen ergeben, dass ich wohl mit so etwas am nächsten ran komme:

Code: Alles auswählen

@property
def encapsulated_bla(self):
    if self.bla is None:
        return 0
    return self.bla
Das wäre unschön, weil ich dann im gesamten Projekt lesende Zugriffe auf 'bla' editieren müsste.
Gibt es dafür eine elegantere Lösung?
Sirius3
User
Beiträge: 18221
Registriert: Sonntag 21. Oktober 2012, 17:20

Du mußt halt bla umbenennen, damit Du bla als Property benutzen kannst.

Code: Alles auswählen

_bla = models.FloatField('Beschreibung', null=True)

...

@property
def bla(self):
    return self._bla if self._bla is not None else 0
skirnir
User
Beiträge: 36
Registriert: Sonntag 25. Januar 2015, 10:59

Danke für den Denkanstoß!
Falls jemand den Thread später findet:

Die Deklaration muss dann so aussehen, damit Django die Spalte in der zugehörigen Tabelle findet:

Code: Alles auswählen

_bla = models.FloatField('Beschreibung', null=true, db_column='bla')
Benutzeravatar
__blackjack__
User
Beiträge: 13927
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@skirnir: Wobei das natürlich nur geht wenn nirgendwo im Code die Unterscheidung zwischen eine Wert der da und 0 ist und einem nicht vorhandenen Wert gemacht werden darf, denn das geht ja nun nicht mehr.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
skirnir
User
Beiträge: 36
Registriert: Sonntag 25. Januar 2015, 10:59

@__blackjack__: Ja, das stimmt natürlich. Muss ich im Hinterkopf behalten. Danke.
Antworten