9

I'm using Django 2.x

I have a model like

class MyModel(models.Model):
    name = models.CharField()
    balance = models.IntegerField()

I want to change the value of balance on the GET request without changing the value in the database.

Like if it could be @Property field, the model will look like

class MyModel(models.Model):
    name = models.CharField()
    balance = models.IntegerField()

    @property
    def balance(self):
        if balance:
           return balance
        return 0.15 * 50

But redeclaration is not allowed. How can I solve this issue?

Note: Field should be compatible with ModelAdmin and DRF Serializer

rahul.m
  • 5,678
  • 3
  • 18
  • 44
Anuj TBE
  • 8,104
  • 17
  • 113
  • 250

1 Answers1

19

There are two ways. Either by using a getter/setter and hide the actual table field. That would allow you to use myobject.balance like any regular field in the model, assigning to it with myobject.balance = 123 and reading from it print(myobject.balance) etc.

class MyModel(models.Model):
    name = models.CharField()
    _balance = models.IntegerField()

    @property
    def balance(self):
        if self._balance:
           return self._balance
        return 0.15 * 50

    @balance.setter
    def balance(self, value):
        self._balance = value

Using a leading _ is the Python convention for "hidden" (private) fields.

A second and simpler way would be to simply use a get_balance() function, and not use a property.

    def get_balance(self):
        if self.balance:
           return self.balance
        return 0.15 * 50
C14L
  • 11,487
  • 4
  • 34
  • 50
  • imagine I already had the field, can I add getter/setter and change the field name without causing migrations? something like `_balance = models(db_field_name='balance')` – EralpB Aug 05 '20 at 17:18
  • 3
    Disclaimer: cannot use the first method to make database entries using balance using a serializer in DRF – Nikhil Pareek Aug 18 '20 at 19:58