czy właściwości działają na polach modelu django?
Myślę, że najlepszym sposobem na zadanie tego pytania jest użycie jakiegoś kodu... mogę to zrobić? (edit : odpowiedź: Nie)
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)
a może muszę to zrobić tak:
Tak, musisz to zrobić tak:
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)
Notatka: możesz zachować nazwę kolumny jako " foo " w bazie danych, przekazując db_column do pola Modelu. Jest to bardzo pomocne, gdy pracujesz na istniejącym systemie i nie chcesz mieć db migracje bez powodu
3 answers
Pole modelu jest już własnością, więc powiedziałbym, że musisz to zrobić w drugi sposób, aby uniknąć kolizji nazw.
Gdy zdefiniujesz Foo = property(..) faktycznie nadpisuje foo = models.. linii, tak aby to pole nie było już dostępne.
Będziesz musiał użyć innej nazwy dla właściwości i pola. W rzeczywistości, jeśli zrobisz to tak, jak w przykładzie #1, Otrzymasz nieskończoną pętlę, gdy spróbujesz uzyskać dostęp do właściwości, ponieważ teraz próbuje ona powrócić siebie.
EDIT: być może powinieneś również rozważyć Nie używanie _foo jako nazwy pola, ale raczej foo, a następnie zdefiniować inną nazwę dla swojej właściwości, ponieważ właściwości nie mogą być używane w QuerySet, więc będziesz musiał użyć rzeczywistych nazw pól, gdy wykonasz na przykład filtr.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-21 15:02:00
Jak wspomniano, poprawna alternatywa dla implementacji własnego django.db.modelki.Klasa pola, należy użyć argumentu - db_column oraz niestandardowego (lub ukrytego) atrybutu klasy. Po prostu przepisuję kod w edycji przez @ Jiaaro zgodnie z bardziej rygorystycznymi konwencjami dla OOP w Pythonie (np. jeśli _foo powinno być faktycznie Ukryte):
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 zostanie rozwiązane do _MyModel__foo (Jak widać przez dir(..) ) tak Ukryte (prywatne ). Zauważ, że ten formularz pozwala również na użycie @ property decorator, co byłoby ostatecznie ładniejszym sposobem napisania czytelnego kodu.
Ponownie, django utworzy tabelę * _MyModel z dwoma polami fooi bar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-30 01:28:30
Poprzednie rozwiązania cierpią, ponieważ @ property powoduje problemy w adminie i .filter(_foo).
Lepszym rozwiązaniem byłoby nadpisanie setattr z tym wyjątkiem, że może to powodować problemy z inicjalizacją obiektu ORM z DB. Jest jednak sztuczka, aby to obejść i jest uniwersalna.
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()
Sekretem jest ' attrname in self.__ dict _ _ ". Gdy model inicjalizuje się z new lub uwodniony z __dict _ _ !
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-24 17:16:12