Django Template System, Calling a Function Inside a Model

How to call a function in template which is defined in a Django model?

You can directly annotate the aggregation, for example:

Invoice.objects.aggregate(amount = Sum('selling_price'))

The resulting dictionary will have a key called amount. If no such alias were specified, it would be the rather long selling_price__sum

Since it returns a dict, you can get the value through:

class YourModel(models.Model):

@property
def get_total(self):
amount = Invoice.objects.aggregate(amount = Sum('selling_price'))['amount']
return amount

# template
{{ item.get_total }} would only get amount value out, not dict

BTW:

Adding extra manager methods is the preferred way to add “table-level”
functionality to your models. (For “row-level” functionality – i.e.,
functions that act on a single instance of a model object

Aggregation is a table level function, since it calculate the sum of multiple objects, which is better defined as manager method instead at model instance level.

class InvoiceManager(models.Manager):
def get_total(self):
return self.aggregate(amount = Sum('selling_price'))['amount']

class Invoice(models.Model):
product_name = models.CharField(max_length=255)
purchase_date = models.DateTimeField(auto_now=True)
cost_price = models.IntegerField()
selling_price = models.IntegerField()
# customized manager
objects=InvoiceManager()

Views

def your_view(request):
...
context = {
'query_result': Invoice.objects.all()
'amount': Invoice.objects.get_total()
}
return render(request, 'index.html', context)

How to call a function from models.py to views or template

First of all, you are referencing fields that do not exist in the model, such as overtime_hours_pay and gross-income. If you do self.someFieldName on a model instance, that field should be defined or inherited in the model. So this is wrong:

self.overtime_hours_pay = self.overtime_hours * 64

You could either

  • Add those fields in the model definition
  • Remove the self part and make them normal variables. Which would look like:
def salary_calculation(self):
overtime_hours_pay = self.overtime_hours * 64

gross_income = self.basic_pay + self.overtime_hours + self.allowance

self.days_leave = self.days_leave * 512
pagibig = self.basic_pay * 0.01
gsis = self.basic_pay * 0.09
withholdingtax = self.basic_pay * 0.15
philhealth = self.basic_pay * 0.0275 / 2

total_deductions = self.days_leave + pagibig + gsis + withholdingtax + philhealth

net_pay = gross_income - total_deductions

return net_pay

After doing that, you could calculate net_pay in the view.

...
if employee_match:
# calculation
net_pay = employee_match.salary_calculation()
# then pass this to the template
return render (request, 'employee.html', {'Search': employee_match, 'net_pay': net_pay})
else:
messages.error(request, 'No results found.')

How to call function that takes an argument in a Django template?

You cannot call a function that requires arguments in a template. Write a template tag or filter instead.

How to call the methods of the model in django template?

You can simply call these in a variable. So if you passed an Invoicetracker object to a template with the name invoicetracker, you can render this with:

{{ invoicetracker.totalbill }}

Note that you can not use brackets here. If the item is a callable, the template will automatically call it without parameters. Methods that thus have parameters, can not be called, or at least not without some extra "tricks".

That being said, here your method does not depend on the self. So that makes it more fit for a @staticmethod or @classmethod. For example:

class  Invoicetracker(models.Model):
# …

@classmethod
def totalbill(cls):
return cls.objects.aggregate(TotalBillAmount=Sum('BillAmount'))['TotalPaid']

@classmethod
def totalpaid(cls):
return cls.objects.aggregate(TotalPaid=Sum('TotalPaid'))['TotalPaid']

Then you can call these methods in your view, and pass the result to the template:

def some_view(request):
total_paid = Invoicetracker.totalbill()
total_bill = Invoicetracker.totalbill()
return render(request, 'order.html', {'total_paid': total_paid, 'total_bill': total_bill})

Call methods in Django Template

Yes, as commented above, this question has duplicates (How to call function that takes an argument in a Django template?).

What you want to do is create a custom template tag (https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#writing-custom-template-tags) like so...

# template
<p>Can Edit: {% can_edit_report user_id report_id %}.</p>

# template_tags.py
from django import template

def can_edit_report(parser, token):
try:
# tag_name is 'can_edit_report'
tag_name, user_id, report_id = token.split_contents()
# business logic here (can user edit this report?)
user = User.objects.get(pk=user_id)
report = Report.objects.get(pk=report_id)
can_edit = user.can_edit_report(report)
except ValueError:
raise template.TemplateSyntaxError("%r tag requires two arguments" % token.contents.split()[0])
return can_edit


Related Topics



Leave a reply



Submit