Reputation: 895
Not sure if I am on a completely wrong track, but I want some kind of a temporary runtime variable/field in my Django model. Currently I have this:
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)
The aa_seq
variable is a temporary value that should not be stored in the database. Nevertheless, to not re-compute the value for each method when multiple methods are to be used, I want to optionally give it as a parameter. I see that giving the aa_seq
as a parameter in each method is redundant and also not object-oriented. Now I wonder if it is a good idea (and possible at all) to store it as a class property like:
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
However, I haven't found any similar examples where model fields and non-model fields were mixed...is there a reason for that?
Upvotes: 2
Views: 440
Reputation: 3223
Your idea's good, but your nomenclature is confused.
There's absolutely nothing wrong with storing it as an instance attribute. It's not a field, and that it's on a model is coincidental. Models are just special cases of classes.
Here is an example of non-field attributes being defined on a Model
subclass in the Django docs themself.
Upvotes: 3
Reputation: 12068
Looks like something cached_property
can do:
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()
You can then just use self.aa_seq
like you currently have, and you can remove the if not aa_seq
checks as it's not needed anymore. Additionally this will cache the computed value of aa_seq
for the lifetime of the instance without storing anything to the DB.
Upvotes: 0