Home > Software design >  How can i compute a result from related models in django
How can i compute a result from related models in django

Time:08-02

class Function(models.Model):
    name = models.CharField(max_length=200)
    def __str__(self):
        return str(self.name)

class Fractions(models.Model):
  fraction = models.DecimalField( max_digits = 5,decimal_places = 2)
  def __str__(self):
    return str(self.fraction)

 class Project(models.Model):
    func= models.ForeignKey(Function, on_delete=models.SET_NULL, null=True)
    fraction= models.ForeignKey(Fraction, on_delete=models.SET_NULL, null=True)
    ratio = models.IntegerField(max_lenght=200)

What i am trying to do if Function.name equals = "x" multiply specific Fractions.fraction by 4 and assign the result to ratio

CodePudding user response:

If the ratio depends entirely on the Function and Fraction, it makes not much sense to store this. Then you can just implement this as a propery, like:

class Function(models.Model):
    name = models.CharField(max_length=200)

    def evaluate(self, x):
        if self.name == 'x':
            return 4 * x
        return x

    def __str__(self):
        return str(self.name)


class Fraction(models.Model):
    fraction = models.DecimalField(max_digits=5, decimal_places=2)

    def __str__(self):
        return str(self.fraction)


class Project(models.Model):
    func = models.ForeignKey(Function, on_delete=models.SET_NULL, null=True)
    fraction = models.ForeignKey(Fraction, on_delete=models.SET_NULL, null=True)

    @property
    def ratio(self):
        if self.func is not None and self.fraction is not None:
            return self.func.evaluate(self.fraction.fraction)

It will thus determine the ratio by fetching the Function object, and calling .evaluate(…). In case the name is x, it will return the value times four, otherwise it will return the value itself.

CodePudding user response:

Assuming that Functions names are unique:

project = Project.objects.get(func__name='x')
return project.fraction.fraction * project.ratio

CodePudding user response:

Just to add to the other answers, you can use python's operator library to perform the operations and insert them into a dict. I would suggest combining this with choices on your name field - though note the choice cannot be an operator function but a string value.

import operator 

FUNCTIONS = {
    ' ': operator.add,
    '-': operator.sub,
    '*': operator.mul,
    '/': operator.truediv
}

class Function(models.Model):
    name = models.CharField(max_length=200)

    def __str__(self):
        return str(self.name)

    def evaluate(self, a, b)
        op = FUNCTIONS.get(self.name)
        if op:
            return op(a, b)
        return None
  • Related