broinjc
broinjc

Reputation: 2699

Model field based on other fields?

Can I have a model field be based on other fields? For example:

class Foo(models.Model):
    x = models.PositiveSmallIntegerField()
    y = models.PositiveSmallIntegerField()
    z = models.PositiveSmallIntegerField()

    score = models.PositiveSmallIntegerField(default=x+y+z)

Upvotes: 12

Views: 12304

Answers (3)

Lord Elrond
Lord Elrond

Reputation: 16072

As of Django 5.0, GeneratedField is the best solution to your problem.

The docs on GeneratedField:

A field that is always computed based on other fields in the model. This field is managed and updated by the database itself. Uses the GENERATED ALWAYS SQL syntax.

from django.db import models
from django.db.models import F


class Foo(models.Model):
    x = models.PositiveSmallIntegerField()
    y = models.PositiveSmallIntegerField()
    z = models.PositiveSmallIntegerField()

    score = models.GeneratedField(
        expression = F('x') + F('y') + F('z'),
        output_field = models.IntegerField(),
        db_persist = True
    )

Upvotes: 2

Daryl Lukas
Daryl Lukas

Reputation: 155

How about this?

class Foo(models.Model):
     x = models.PositiveSmallIntegerField()
     y = models.PositiveSmallIntegerField()
     z = models.PositiveSmallIntegerField()

     @property
     def score(self):
         return self.x + self.y + self.z

Official docs on Model Methods here

Upvotes: 10

karthikr
karthikr

Reputation: 99680

Yes, the best way to handle this would be to override the save method of the model

class Foo(models.Model):
    x = models.PositiveSmallIntegerField()
    y = models.PositiveSmallIntegerField()
    z = models.PositiveSmallIntegerField()

    score = models.PositiveSmallIntegerField()

    def save(self, *args, **kwargs):
        self.score = self.x + self.y + self.z
        super(Foo, self).save(*args, **kwargs) # Call the "real" save() method.

Make sure you take care of the necessary validations.

More on this here: official documentation

Upvotes: 25

Related Questions