Когда django вычисляет свойства, которые не хранятся в БД - PullRequest
0 голосов
/ 27 сентября 2018

Быстрый вопрос о производительности.Допустим, у нас есть какая-то модель:

class MyModel(models.Model):
    number = models.IntegerField(default=0)

    def getComplicatedNumber(self):
        # do some complex calculations here, including other db calls
        return 0 # really return the complex calculation

    otherNum = property(getComplicatedNumber)

Тогда, скажем, у нас есть представление:

modelObject.otherNum

или в шаблоне:

{{ modelObject.otherNum }}

Мой вопрос: когда рассчитывается этот атрибут / свойство при создании объекта со свойством?Рассчитывается ли он только тогда, когда он вызывается в представлении или шаблоне, или он рассчитывается всякий раз, когда этот объект извлекается или когда создается экземпляр этого класса?Я полагаю, что это снизит производительность, если ее часто вычислять и не использовать в представлениях или шаблонах.

Спасибо

1 Ответ

0 голосов
/ 27 сентября 2018

Мой вопрос: когда рассчитывается этот атрибут / свойство при создании объекта со свойством?Он рассчитывается только при вызове в представлении или шаблоне или при каждом извлечении этого объекта или при создании экземпляра этого класса?

Он вычисляется каждый раз вы получите это.Поэтому, если вы напишите:

modelObject.otherNum  # call getComplicatedNumber() the first time
modelObject.otherNum  # call getComplicatedNumber() the second time

getComplicatedNumber называется дважды .

Это не , рассчитанное заранее (так что если высвойство никогда не понадобится, оно никогда не будет вычисляться), а также кэшировано (после вычисления значение не сохраняется для предотвращения его повторного вычисления).

Можно, конечно,реализовать кеш, например:

# possible implementation of a cache

class MyModel(models.Model):
    number = models.IntegerField(default=0)

    def getComplicatedNumber(self):
        if <b>not hasattr(self, '_complicated')</b>:
            # do some complex calculations here, including other db calls
            <b>self._complicated = 0</b>  # really return the complex calculation
        return <b>self._complicated</b>

    otherNum = property(getComplicatedNumber)

Обратите внимание, что если атрибуты и параметры, от которых зависит метод, изменятся, кеш не автоматически станет недействительным.

Этокэшированная версия не вычислит значение, если оно вам не нужно.

...