Azhagusundaram Tamil
Azhagusundaram Tamil

Reputation: 2391

Django admin: How to show calculated value from entered values dynamically in Django admin form page?

I have a form which is having a 'price', 'tax' and 'discount' fields (IntegerFields). And then one more read-only field will be there called 'total_price'.

while we enter the 'price', 'discount' and 'tax', automatically 'total_price' value should display. If we change the 'discount' or 'price' then 'total_price' also change immediately.

After seeing the final price, we can click the 'Save' button.

How to attain this in Django admin?

Upvotes: 1

Views: 1866

Answers (1)

Michał
Michał

Reputation: 503

To do this, you will have to add custom Javascript code to your admin page.

Here's what you can do:

  1. Add read-only field to admin - it will display "total_price"
  2. Add custom script to admin page.
  3. Write JS script - this script will do "live update" of total price

Your admin may look like this:

@admin.register(YourModel)
class YourModelAdmin(admin.ModelAdmin):

    # some code here...

    readonly_fields = ('total_price', )

    def total_price(self, obj):
        # return whatever initial value you want
        return obj.price - obj.price*obj.discount

    # This is important - adding custom script to admin page
    @property
    def media(self):
        media = super().media
        media._js.append('js/your-custom-script.js')
        return media

Remember that js/your-custom-script.js must be in your static files folder.

UPDATE: Instead of overwriting media property, you can include your JS using Meta nested class:

class YourModelAdmin(admin.ModelAdmin):
    ...
    class Media:
        js = (
            'path-to-your-static-script-file.js',
        )

The last step is to write a script to update value of total_price field whenever some other field is changed.

Example: if you want to change total_price whenever price is changed, your script can look like this:

if (!$) {
    $ = django.jQuery;
}
$(document).ready(function(){
    // Add event listener to "price" input
    $("#id_price").change(function(e){
        // Get entered value
        let price = parseFloat($(this).val());

        // Get discount value from another field 
        let discount = parseFloat($("#id_discount").val())

        // Compute total price in whatever way you want
        let total_price = price - price*discount;

        // Set value in read-only "total_price" field.
        $("div.field-total_price").find("div.readonly").text(total_price);
    });
})

If you want to update total_price when discount or tax fields are changed, simply add event listeners to them.

Upvotes: 3

Related Questions