Ryan Tice
Ryan Tice

Reputation: 731

Calculating total cost and adding sales tax to shopping cart

I am creating a basic shopping cart application, I can get in my cart all of the items to populate with the quantity and cost, but I am trying to find a way thats I can create a total cost, and adding sales tax on top of that. Clearly the total line is the issue, but I am not sure what I could do to populate price and quantity for all products and multiply them together.

{% for addtocart in userCart %}
  <li>Quantity:{{addtocart.quantity}} <a href="/products/{{addtocart.product.id}}">{{addtocart.product.prodName}}</a> ${{addtocart.product.prodPrice}}(<a
href=/delItem/{{addtocart.id}}>Remove</a>)<br>
{% endfor %}
</ul>
{% else %}
<p> No products available </p>
{% endif %}
***<p>Total: {{addtocart.quantity}}"x"{{addtocart.product.prodPrice}}***

views.py

def addtocart(request, prod_id):
        if (request.method == 'POST'):
                form = CartForm(request.POST)
                if form.is_valid():
                        newComment = form.save()
                        newComment.session = request.session.session_key[:20]
                        newComment.save()
                        return HttpResponseRedirect('/products/' + str(newComment.product.id))
        else:
                form = CartForm( {'name':'Your Name', 'session':'message', 'product':prod_id} )

        return render_to_response('Products/comment.html', {'form': form, 'prod_id': prod_id})

def userHistory(request):
        userCart = Cart.objects.filter(session = request.session.session_key[:20])
        return render_to_response('Products/history.html', {'userCart':userCart})

models.py

from django.db import models
from django.forms import ModelForm

# Create your models here.
class prod(models.Model):
        prodName = models.CharField(max_length=100)
        prodDesc = models.TextField()
        prodPrice = models.FloatField()
        prodImage = models.ImageField(upload_to="userimages/")
        def __unicode__(self):
                return self.prodName

class Cart(models.Model):
        session = models.CharField(max_length=100)
        product = models.ForeignKey('prod')
        quantity = models.IntegerField()

        def __unicode__(self):
                return self.name

class CartForm(ModelForm):
        class Meta:
                model = Cart
                exclude = ('session')

Upvotes: 0

Views: 3285

Answers (3)

Jordan Reiter
Jordan Reiter

Reputation: 21032

Instead of putting this in your view, I would make it a function under your model. This way if you have to calculate the total elsewhere in your app, you don't have to reuse the same code.

The real problem is that you are using an incorrect model. Users have only one shopping cart, not many. So you should use the following models instead:

class Cart(models.Model):
    session = models.CharField(max_length=100)

class CartItem(models.Model):
    cart = models.ForeignKey('Cart', related_name='items')
    product = models.ForeignKey('prod') 
    quantity = models.IntegerField()

Then, you add the total function to the Cart model:

class Cart(models.Model):
    session = models.CharField(max_length=100)
    items = models.ManyToManyField(prod, through="CartProduct")

    def total(self):
        total = 0.0
        for item in self.items.all():
            total += (item.product.prodPrice * item.quantity)
        return total

I would also seriously recommend renaming the prod model to Product and renaming the fields as well to match Django naming conventions.

Upvotes: 0

bytejunkie
bytejunkie

Reputation: 1033

quick note: you're not recording the price at the time of addition to cart. this might be an issue on some carts. depends on the shop.

Upvotes: 0

cberner
cberner

Reputation: 3040

There are two ways you can do this:

  1. compute the total in your view, and pass it in as a separate variable
  2. define a custom template tag that does multiplication (Django doesn't have one by default)

(1) in more detail:

In your view:

def userHistory(request):
    userCart = Cart.objects.filter(session = request.session.session_key[:20])
    totalCost = 0
    for item in userCart:
        totalCost += item.quantity * item.product.prodPrice
    return render_to_response('Products/history.html', {'userCart':userCart,
        'totalCost': totalCost})

Then in your template: <p>{{totalCost}}</p>

(2) in more detail:

First make a new file my_app/templatetags/my_tags.py (also put an __init__.py file in this directory, so that Python knows it's a package)

from django import template
register = template.Library()

@register.filter 
def multiply(arg1, arg2): 
    return float(arg1) * float(arg2)

Then in your template add {% load my_tags %} at the top, and you'll be able to use {{addtocart.quantity|multiply:addtocart.product.prodPrice}}

Upvotes: 2

Related Questions