Mache Eigenschaften auf django-Modellfeldern?

Ich denke, der beste Weg, um diese Frage zu stellen ist mit einigen Code … kann ich das tun? ( Bearbeiten : ANTWORT: nein)

  • Warum bekomme ich diesen Fehler in Django?
  • Hinzufügen einer Variablen in Content Disposition Antwortdatei name-python / django
  • Django - Login und Weiterleitung zur Benutzerprofilseite
  • Multiply in django Vorlage
  • Verwenden von Django-Modellformularen + Formular-Assistenten + Crispy - geht nicht zum zweiten Schritt
  • Wie man eine Fehlermeldung in django benutzerdefinierte Authentifizierung Backend haben
  • class MyModel(models.Model): 
    foo = models.CharField(max_length = 20)
    bar = models.CharField(max_length = 20)

      def get_foo(self): if self.bar: return self.bar else: return self.foo def set_foo(self, input): self.foo = input foo = property(get_foo, set_foo) 

    Oder muss ich das so machen:

    Ja, das musst du so machen:

     class MyModel(models.Model): _foo = models.CharField(max_length = 20, db_column='foo') bar = models.CharField(max_length = 20) def get_foo(self): if self.bar: return self.bar else: return self._foo def set_foo(self, input): self._foo = input foo = property(get_foo, set_foo) 

    Anmerkung : Sie können den Spaltennamen als 'foo' in der Datenbank behalten, indem Sie eine db_column an ​​das Modellfeld übergeben. Dies ist sehr hilfreich, wenn Sie an einem bestehenden System arbeiten und Sie nicht wollen, db Migrationen ohne Grund zu tun

    3 Solutions collect form web for “Mache Eigenschaften auf django-Modellfeldern?”

    Ein Modell-Feld ist bereits Eigentum, also würde ich sagen, dass du es tun musst, den zweiten Weg, um einen Namen-Zusammenstoß zu vermeiden.

    Wenn du foo = property (..) definierst, überschreibt es tatsächlich die Zeile foo = models .., so dass das Feld nicht mehr zugänglich ist.

    Sie müssen einen anderen Namen für die Eigenschaft und das Feld verwenden. In der Tat, wenn Sie es so machen, wie Sie es in Beispiel # 1 haben, erhalten Sie eine Endlosschleife, wenn Sie versuchen, auf die Eigenschaft zuzugreifen, da es jetzt versucht, sich zurückzugeben.

    EDIT: Vielleicht sollten Sie auch nicht mit _foo als Feldname, sondern eher foo, und dann definieren einen anderen Namen für Ihre Eigenschaft, weil Eigenschaften können nicht in QuerySet verwendet werden, so müssen Sie die tatsächlichen Feldnamen verwenden, wenn Sie ein Filter zum Beispiel.

    Wie bereits erwähnt, eine richtige Alternative zur Implementierung Ihrer eigenen django.db.models.Field Klasse, sollte man – db_column Argument und ein benutzerdefiniertes (oder verstecktes) Klassenattribut verwenden. Ich schreibe gerade den Code in der Bearbeitung von @Jiaaro nach strengeren Konventionen für OOP in Python (zB wenn _foo sollte eigentlich versteckt):

     class MyModel(models.Model): __foo = models.CharField(max_length = 20, db_column='foo') bar = models.CharField(max_length = 20) @property def foo(self): if self.bar: return self.bar else: return self.__foo @foo.setter def foo(self, value): self.__foo = value 

    __foo wird in _MyModel__foo (wie von dir (..) gesehen ) so versteckt ( privat ) gelöst. Beachten Sie, dass dieses Formular auch die Verwendung von @ property Dekorateur erlaubt, die letztlich eine schönere Art wäre, lesbaren Code zu schreiben.

    Wieder wird django * _MyModel Tisch mit zwei Feldern foo und bar erstellen.

    Die bisherigen Lösungen leiden, weil @property Probleme in admin und .filter (_foo) verursacht.

    Eine bessere Lösung wäre, setattr zu überschreiben, außer dass dies Probleme beim Initialisieren des ORM-Objekts aus dem DB verursachen kann. Allerdings gibt es einen Trick, um dies zu umgehen, und es ist universell.

     class MyModel(models.Model): foo = models.CharField(max_length = 20) bar = models.CharField(max_length = 20) def __setattr__(self, attrname, val): setter_func = 'setter_' + attrname if attrname in self.__dict__ and callable(getattr(self, setter_func, None)): super(MyModel, self).__setattr__(attrname, getattr(self, setter_func)(val)) else: super(MyModel, self).__setattr__(attrname, val) def setter_foo(self, val): return val.upper() 

    Das Geheimnis ist " attrname in self .__ dict__ ". Wenn das Modell entweder von neuem oder hydratisiertem aus dem __dict__ initialisiert wird !

    Python ist die beste Programmiersprache der Welt.