简体   繁体   中英

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

I am extremely newbie to Django, Sorry in the advance for asking the wrong question.

I want to create a function to sum the values of a column and call it on my template in Django.

Model:

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()

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

I created this get_total function to sum of the values of selling_price column.

Template Code:

    {% for item in query_result %}
        <tr>
            <td>{{item.product_name}}</td>
            <td>{{item.cost_price}}</td>
            <td>{{item.selling_price}}</td>
            {{item.get_total}}
        </tr>
    {% endfor %}

Here's the problem, after passing the data, whenever I call this function, the data is shown multiple times in the template.

Here's the output. Output Image

I know it's quite silly, but I am unable to figure it out.

Help, Please.

You can directly annotate the aggregation , for example:

Invoice.objects.aggregate()

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 – ie, 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
    

Views

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM