WindCheck
WindCheck

Reputation: 426

Math on Django queryset field

I have the following Django model:

class Accounts(models.Model):
    account_code = models.CharField(max_length=12)
    account_name = models.CharField(max_length=50)
    value = models.DecimalField(max_digits=10, decimal_places=2)

When a query the database I want the returned queryset to have its field value divided by 1000. How can I do this kind of math on a model field as I query the database?

Upvotes: 0

Views: 931

Answers (2)

Henry Woody
Henry Woody

Reputation: 15662

You can define a property on your model using the property decorator. This property would not be defined in the database, but would be accessible on each object once queried.

For example:

class Accounts(models.Model):
    account_code = models.CharField(max_length=12)
    account_name = models.CharField(max_length=50)
    value = models.DecimalField(max_digits=10, decimal_places=2)

    @property
    def divided_value(self):
        return self.value / 1000

Then you can access the divided_value on each account instance as a normal property, e.g. account.divided_value.

Upvotes: 1

rchurch4
rchurch4

Reputation: 899

I'm not certain that this is actually possible to do in a queryset, even using annotation (I'm actually pretty certain that it's not possible). My first answer is space inefficient, as you'd have to store the same value in two forms, and my second answer is what I would do, and uses the front end to handle the division:

Answer One: A second value field

In your model, you can define a field formatted_value that is also a decimal, but with 6 decimal places (to account for the division by 1000). In the save function, or in a pre_save signal, you can divide value by 1000 and save that in the formatted_value field.

This answer is sub-optimal because you will waste space in your database. I believe that a better answer is this:

Answer Two: View or Front End Handling

In my projects, I often need to manipulate numbers held in the database to output some sort of analytics tool. I return the raw numbers to the front end (as long as they are not sensitive), and then handle the math in the front end using Javascript. This passes the burden of computation to the client, and simplifies your Django. The pro of this is that you can then make the front end interactive and allow the user to change values that affect the analytics they are looking at.

I have a feeling that you are looking for something simpler. If you have a view that always needs to return the value/1000, you can handle this in your view by getting your list of Accounts using Accounts.objects.all() and then looping through each and dividing value by 1000.

Upvotes: 1

Related Questions