Afrowave
Afrowave

Reputation: 940

Django - Coleman

I am a noob in Django and I started a project that is to have a shopping cart/ e-commerce solution.

I have been reading into Django 1.2 e-commerce book by Jesse Legg and I am looking for someone who has gone through it to some extent. I apologise that I might not be specific enough in my question.

After setting up the Django-registration and Django-profiles, the book is to show how one creates a working shopping cart and associate it with a customer. No problem.

Somewhere in Chapter 3, we create the order, status of order models and the views to load products into the cart.

I am getting an error that my "Item" is not defined. The only place "Item" appears in in the Cart object:

class Cart(object):
    class Item(object):
        def __init__(self, itemid, product, quantity=1):
            self.itemid = itemid
            self.product = product
            self.quantity = quantity

    def __init__(self):
        self.items = list()
        self.unique_item_id = 0

    def _get_next_item_id(self):
        self.unique_item_id += 1
        return self.unique_item_id
    next_item_id = property(_get_next_item_id)

    def add_item(self, product, quantity=1):
        item = Item(self.next_item_id, product, quantity)
        self.items.push(item)

    def is_empty(self):
        return self.items == []

    def empty(self):
        self.items = list()

    def remove_item(self, itemid):
        self.items = filter(lambda x: x.itemid != itemid, self.items)

    def __iter__(self):
        return self.forward()

    def forward(self):
        current_index = 0
        while (current_index < len(self.items)):
            item = self.items[current_index]
            current_index += 1
            yield item

(Thanks, vicvicvic) Here is the code I'm dealing with.

The models:

class Order(models.Model):
...
    customer = models.ForeignKey(User, blank=True, null=True)
    status_code = models.ForeignKey('StatusCode')
    date_placed = models.DateTimeField()
    total_price = models.DecimalField(max_digits=7, decimal_places=2)
    comments = models.TextField(blank=True)
    products = models.ManyToManyField(Product, through='ProductInOrder')
...


class ProductInOrder(models.Model):
...
    order = models.ForeignKey(Order)
    product = models.ForeignKey(Product)
    unit_price = models.DecimalField(max_digits=7, decimal_places=2)
    quantity = models.PositiveIntegerField()
    total_price = models.DecimalField(max_digits=7, decimal_places=2)
    comments = models.TextField(blank=True)
...

class StatusCode(models.Model):
...
    short_name = models.CharField(max_length=10)
    name = models.CharField(max_length=300)
    description = models.TextField()
...

The views in question:

from django.http import Http404
from django.shortcuts import render_to_response
from django.template import RequestContext
from coleman.orders.cart import Cart
from coleman.products.models import Product

def lookup_object(queryset, object_id=None, slug=None, slug_field=None):
    if object_id is not None:
        obj = queryset.get(pk=object_id)
    elif slug and slug_field:
        kwargs = {slug_field: slug}
        obj = queryset.get(**kwargs)
    else:
        raise Http404
    return obj

def get_shopping_cart(request, cart_class=Cart):
    return request.session.get('cart', None) or cart_class()

def update_shopping_cart(request, cart):
    request.session['cart'] = cart

def shopping_cart(request, template_name='orders/shopping_cart.html'):
    cart = get_shopping_cart(request)
    ctx = {'cart': cart}
    return render_to_response(template_name, ctx, context_instance=RequestContext(request))


def add_to_cart(request, queryset, object_id=None, slug=None, slug_field='slug', template_name='orders/add_to_cart.html'):
...
    obj = lookup_object(queryset, object_id, slug, slug_field)
    quantity = request.GET.get('quantity', 1)
    cart = get_shopping_cart(request)
    cart.add_item(obj, quantity)
    update_shopping_cart(request, cart)
    ctx = {'object': obj, 'cart': cart}
    return render_to_response(template_name, ctx, context_instance=RequestContext(request))
...

def remove_from_cart(request, cart_item_id, template_name='orders/remove_from_cart.html'):
...
    cart = get_shopping_cart(request)
    cart.remove_item(cart_item_id)
    update_shopping_cart(request, cart)
    ctx = {'cart': cart}
    return render_to_response(template_name, ctx,
                              context_instance=RequestContext(request))

def checkout(request, template_name='orders/checkout.html'):

    cart = get_shopping_cart(request)
    googleCart, googleSig = doGoogleCheckout(cart)
    ctx = {'cart': cart,
           'googleCart': googleCart,
           'googleSig': googleSig,
           'googleMerchantKey': settings.GOOGLE_MERCHANT_KEY,
           'googleMerchantID': settings.GOOGLE_MERCHANT_ID}
    return render_to_response(template_name, ctx, context_instance=RequestContext(request))

And my product detail page:

{% block content %}

    <h1>{{ object.name }}</h1>
    <p>{{ object.description }}</p>
    <p>Price: ${{ object.price_in_dollars }}</p>
    {% for detail in object.details.all %}
    {% if forloop.first %}<p>Additional details:</p>{% endif %}
    <li>{{ detail.attribute.name }}: {{ detail.value }}</li>
    {% endfor %}
    <hr/>

 <form action="/orders/cart/add/{{ object.slug }}/" method="POST">{% csrf_token %}
  <input name="item_name_1" type="hidden" value="{{ object.name }}"/>
  <input name="item_description_1" type="hidden" value="{{ object.description }}"/>
  <input name="item_quantity_1" type="hidden" value="1"/>
  <input name="item_price_1" type="hidden" value="0.5"/>
  <input name="item_currency_1" type="hidden" value="USD"/>
  <input name="_charset_" type="hidden" value="utf-8"/>
  <input type="submit" value="Add To Cart">
 </form>

<p><a href="{% url product_list %}">Back to product list</a></p>
 {% endblock %}

The error I get is:

global name 'Item' is not defined
Exception Location: .../ecommerce_book/coleman/orders/views.py in add_to_cart, line 41

Line 41 in the view "add_to_cart" refers to "cart.add_item(obj, quantity)"

Thanks.

Upvotes: 0

Views: 806

Answers (2)

Hollister
Hollister

Reputation: 3918

Since Item is nested in Cart, you need to provide the proper scope. Change add_item to:

def add_item(self, product, quantity=1):
        item = Cart.Item(self.next_item_id, product, quantity)
        self.items.push(item)

Alternatively, self.Item(...) will also work.

Upvotes: 1

Timbadu
Timbadu

Reputation: 1551

I don't know the book. But until someone who has read it can help. Here's my tupence worth.

The error is happening on line 41 in your views.py file. There aren't 41 lines in the views.py you've uploaded.

Is there a model class of Item somewhere in your app? If so try importing it along with Product and Cart.

Upvotes: 0

Related Questions