Django Класс модели с временным немодельным полем

Не уверен, что я нахожусь на совершенно неправильном пути, но мне нужна какая-то временная переменная/поле в моей модели Django. В настоящее время я имею следующее:

class BioChemicalProperties(models.Model):
    mw = models.FloatField(blank=True, null=True)
    iep = models.FloatField(blank=True, null=True)
    exco = models.FloatField(blank=True, null=True)
    molar_exco = models.FloatField(blank=True, null=True)
    e01 = models.FloatField(blank=True, null=True)

    def get_protein(self):
        aa_seq = self.ab.get_lc_protein()
        aa_seq += self.ab.get_hc_protein()
        return aa_seq

    def calc_mw(self, aa_seq=None):
        if not aa_seq:
            aa_seq = self.get_protein()
        analysed_seq = ProteinAnalysis(aa_seq)
        self.mw = analysed_seq.molecular_weight() + 18.015

    def calc_exco(self, aa_seq=None):
        if not aa_seq:
            aa_seq = self.get_protein()
        analysed_seq = ProteinAnalysis(aa_seq)
        self.exco = analysed_seq.molar_extinction_coefficient()[1]
    
    #...more methods here...

    def calc_all_bioprops(self, aa_seq=None):
        if not aa_seq:
            aa_seq = self.get_protein()
        self.calc_mw(aa_seq)
        self.calc_iep(aa_seq)
        self.calc_molexco(aa_seq)
        self.calc_e01(aa_seq)

Переменная aa_seq является временным значением, которое не должно храниться в базе данных. Тем не менее, чтобы не вычислять значение заново для каждого метода, когда будет использоваться несколько методов, я хочу опционально передать его в качестве параметра. Я вижу, что передача aa_seq в качестве параметра в каждом методе избыточна и не является объектно-ориентированной. Теперь мне интересно, хорошая ли это идея (и возможно ли это вообще) хранить его как свойство класса, например:

class BioChemicalProperties(models.Model):
    mw = models.FloatField(blank=True, null=True)
    iep = models.FloatField(blank=True, null=True)
    exco = models.FloatField(blank=True, null=True)
    molar_exco = models.FloatField(blank=True, null=True)
    e01 = models.FloatField(blank=True, null=True)
    aa_seq = ""

    def calc_mw(self):
        if not self.aa_seq:
            self.aa_seq = self.get_protein()
        analysed_seq = ProteinAnalysis(self.aa_seq)
        self.mw = analysed_seq.molecular_weight() + 18.015


Однако я не нашел ни одного похожего примера, где бы смешивались поля модели и немодельные поля... есть ли для этого причина?

Похоже, что что-то cached_property может сделать:

from django.utils.functional import cached_property


class BioChemicalProperties(models.Model):
    ...
    @cached_property
    def aa_seq(self):
        return self.ab.get_lc_protein() + self.ab.get_hc_protein()

Затем вы можете просто использовать self.aa_seq, как сейчас, и удалить проверку if not aa_seq, поскольку она больше не нужна. Кроме того, это позволит кэшировать вычисленное значение aa_seq на время жизни экземпляра, не сохраняя ничего в БД.

Ваша идея хороша, но номенклатура перепутана.

Нет абсолютно ничего плохого в том, чтобы хранить его как атрибут instance attribute. Это не поле, и то, что оно находится в модели, случайно. Модели - это просто особые случаи классов.

Вот пример определения атрибутов, не относящихся к полю, для подкласса Model в самой документации Django.

Вернуться на верх