How to do excel sheet like calculations in django Admin?

342 Views Asked by At

I have a below model Student. In Django Admin can I write a code so that when user types the value of "ActualFees" it should check if "BalanceFees" is empty . If it is empty then Paidfees should get copied in BalanceFees otherwise don't copy.

Again if "PaidFees" is typed by user then "BalanceFees" must be calculated as,

BalanceFees = BalanceFees - PaidFees.

How to write code to achive this in Django Admin?

class Student(models.Model):
    GENDER = (
        ('M', 'Male'),
        ('F', 'Female'),)
    BLOOD = (
        ('O+','O+'),
        ('O-','O-'),
        ('A +','A +'),
        ('A -','A -'),
        ('B +','B +'),
        ('B -','B -'),
        ('AB +','AB +'),
        ('AB -','AB -'),
        )
    enroll_no = models.IntegerField()
    Name = models.CharField(max_length=200,help_text='SurName MiddleName     First name ')
    gender = models.CharField(max_length=1,blank = True,choices=GENDER)
    blood_gr = models.CharField(max_length=3,blank = True,choices=BLOOD)
    category = models.CharField(max_length=200,blank = True)
    photo = models.ImageField(upload_to="static",blank = True)
    ActualFees = models.IntegerField(blank = True)
    PaidFees = models.IntegerField(blank = True, null = True)
    BalanceFees = models.IntegerField(blank = True, null = True)
    PermenantAddress = models.TextField(blank = True)
    Parents_Mobile = models.IntegerField(blank = True,default=0)
    Personal_Mobile = models.IntegerField(blank = True,default=0)
    LocalAddress = models.TextField(blank = True)
    Parents_email = models.CharField(max_length=200,blank = True,default='')
    Personal_email = models.CharField(max_length=200,blank = True,default='')

   def __str__(self):
        return self.Name
2

There are 2 best solutions below

3
On

There are two ways to approach this:

  1. Server-side: by catching the save of the AdminForm and then if one field is empty calculating the appropriate other value, with validations to make sure all three fields sum to the right value. The issue with this approach is that if a client turns of javascript they can still enter invalid data
  2. Client-side: writing some custom javascript that will catch changes to the appropriate fields and then sum accordingly on the onblur event.

A mix of both is probably best, and the actual implementation is left as an exercise to the reader.

To add extra scripts in, its as easy as modifying the Media class:

class MyModelAdmin(ModelAdmin):
    class Media:
        js = [
                '/scripts/calculate.js',
            ]
0
On

This is how I have done it. I have edited models.py and added default = 0 in Student models PaidFees and BalanceFees fields. After adding these fields I have perform migrations and all. Also my Previous data remains as it is. I can do calculations in save_model method in admin.py

class Student(models.Model):
    ....
    ....
    ....

    PaidFees = models.IntegerField(blank = True, default = 0)
    BalanceFees = models.IntegerField(blank = True, default = 0)
    ....
    ....

def save_model(self, request, obj, form, change):
    if obj.BalanceFees == 0:
        obj.BalanceFees = obj.ActualFees
    else:
        obj.BalanceFees = obj.BalanceFees-obj.PaidFees
    obj.save()

Still I am curious to know the solution at client side.