*I have two apps "orders" and "carts". In my models for carts I got:*

class CartItem(models.Model):
    cart = models.ForeignKey("Cart")
    item = models.ForeignKey(Variation)
    quantity = models.PositiveIntegerField(default=1)
    line_item_total = models.DecimalField(max_digits=10, decimal_places=2)

    def __unicode__(self):
        return self.item.title

    def remove(self):
        return self.item.remove_from_cart()


def cart_item_pre_save_receiver(sender, instance, *args, **kwargs):
    qty = instance.quantity
    if qty >= 1:
        price = instance.item.get_price()
        line_item_total = Decimal(qty) * Decimal(price)
        instance.line_item_total = line_item_total

pre_save.connect(cart_item_pre_save_receiver, sender=CartItem)

def cart_item_post_save_receiver(sender, instance, *args, **kwargs):
    instance.cart.update_subtotal()
post_save.connect(cart_item_post_save_receiver, sender=CartItem)

post_delete.connect(cart_item_post_save_receiver, sender=CartItem)

class Cart(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True,
blank=True)
    items = models.ManyToManyField(Variation, through=CartItem)
    timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
    updated = models.DateTimeField(auto_now_add=False, auto_now=True)
    subtotal = models.DecimalField(max_digits=50, decimal_places=2,
default=25.00)
    tax_percentage  = models.DecimalField(max_digits=10, decimal_places=5,
default=0.085)
    tax_total = models.DecimalField(max_digits=50, decimal_places=2,
default=25.00)
    total = models.DecimalField(max_digits=50, decimal_places=2,
default=25.00)

    def __unicode__(self):
        return str(self.id)

    def update_subtotal(self):
        print "updating..."
        subtotal = 0
        items = self.cartitem_set.all()
        for item in items:
            subtotal += item.line_item_total
        self.subtotal = "%.2f" %(subtotal)
        self.save()

def do_tax_and_total_receiver(sender, instance, *args, **kwargs):
    subtotal = Decimal(instance.subtotal)
    tax_total = round(subtotal * Decimal(instance.tax_percentage), 2) #8.5%
    print instance.tax_percentage
    total = round(subtotal + Decimal(tax_total), 2)
    instance.tax_total = "%.2f" %(tax_total)
    instance.total = "%.2f" %(total)

pre_save.connect(do_tax_and_total_receiver, sender=Cart)

*In my carts Views.py:*

from orders.forms import GuestCheckoutForm
from orders.mixins import CartOrderMixin
from orders.models import UserCheckout, Order, UserAddress
from products.models import Variation
from .models import Cart, CartItem

if settings.DEBUG:
    braintree.Configuration.configure(braintree.Environment.Sandbox,
    merchant_id=settings.BRAINTREE_MERCHANT_ID,
    public_key=settings.BRAINTREE_PUBLIC,
    private_key=settings.BRAINTREE_PRIVATE)

class ItemCountView(View):
    def get(self, request, *args, **kwargs):
        if request.is_ajax():
            cart_id = self.request.session.get("cart_id")
            if cart_id == None:
                count = 0
            else:
                cart = Cart.objects.get(id=cart_id)
                count = cart.items.count()
            request.session["cart_item_count"] = count
            return JsonResponse({"count": count})
        else:
            raise Http404

class CartView(SingleObjectMixin, View):
    model = Cart
    template_name = "carts/view.html"

    def get_object(self, *args, **kwargs):
        self.request.session.set_expiry(0) #5 minutes
        cart_id = self.request.session.get("cart_id")
        if cart_id == None:
            cart = Cart()
            cart.tax_percentage = 0.075
            cart.save()
            cart_id = cart.id
            self.request.session["cart_id"] = cart_id
        cart = Cart.objects.get(id=cart_id)
        if self.request.user.is_authenticated():
            cart.user = self.request.user
            cart.save()
        return cart

    def get(self, request, *args, **kwargs):
        cart = self.get_object()
        item_id = request.GET.get("item")
        delete_item = request.GET.get("delete", False)
        flash_message = ""
        item_added = False
        if item_id:
            item_instance = get_object_or_404(Variation, id=item_id)
            qty = request.GET.get("qty", 1)
            try:
                if int(qty) < 1:
                    delete_item = True
            except:
                raise Http404
            cart_item, created = CartItem.objects.get_or_create(cart=cart,
item=item_instance)
            if created:
                flash_message = "Successfully added to the cart"
                item_added = True
            if delete_item:
                flash_message = "Item removed successfully."
                cart_item.delete()
            else:
                if not created:
                    flash_message = "Quantity has been updated
successfully."
                cart_item.quantity = qty
                cart_item.save()
            if not request.is_ajax():
                return HttpResponseRedirect(reverse("cart"))
                #return cart_item.cart.get_absolute_url()

        if request.is_ajax():
            try:
                total = cart_item.line_item_total
            except:
                total = None
            try:
                subtotal = cart_item.cart.subtotal
            except:
                subtotal = None

            try:
                cart_total = cart_item.cart.total
            except:
                cart_total = None

            try:
                tax_total = cart_item.cart.tax_total
            except:
                tax_total = None

            try:
                total_items = cart_item.cart.items.count()
            except:
                total_items = 0

            data = {
                    "deleted": delete_item,
                    "item_added": item_added,
                    "line_total": total,
                    "subtotal": subtotal,
                    "cart_total": cart_total,
                    "tax_total": tax_total,
                    "flash_message": flash_message,
                    "total_items": total_items
                    }

            return JsonResponse(data)
        context = {
            "object": self.get_object()
        }
        template = self.template_name
        return render(request, template, context)

class CheckoutView(CartOrderMixin, FormMixin, DetailView):
    model = Cart
    template_name = "carts/checkout_view.html"
    form_class = GuestCheckoutForm

    def get_object(self, *args, **kwargs):
        cart = self.get_cart()
        if cart == None:
            return None
        return cart

    def get_context_data(self, *args, **kwargs):
        context = super(CheckoutView, self).get_context_data(*args,
**kwargs)
        user_can_continue = False
        user_check_id = self.request.session.get("user_checkout_id")
        if self.request.user.is_authenticated():
            user_can_continue = True
            user_checkout, created =
UserCheckout.objects.get_or_create(email=self.request.user.email)
            user_checkout.user = self.request.user
            user_checkout.save()
            context["client_token"] = user_checkout.get_client_token()
            self.request.session["user_checkout_id"] = user_checkout.id
        elif not self.request.user.is_authenticated() and user_check_id ==
None:
            context["login_form"] = AuthenticationForm()
            context["next_url"] = self.request.build_absolute_uri()

        else:
            pass

        if user_check_id != None:
            user_can_continue = True
            if not self.request.user.is_authenticated(): #GUEST USER
                user_checkout_2 = UserCheckout.objects.get(id=user_check_id)
                context["client_token"] = user_checkout_2.get_client_token()

        #if self.get_cart() is not None:
        context["order"] = self.get_order()
        context["user_can_continue"] = user_can_continue
        context["form"] = self.get_form()
        return context

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form = self.get_form()
        if form.is_valid():
            email = form.cleaned_data.get("email")
            user_checkout, created =
UserCheckout.objects.get_or_create(email=email)
            request.session["user_checkout_id"] = user_checkout.id
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

    def get_success_url(self):
        return reverse("checkout")


    def get(self, request, *args, **kwargs):
        get_data = super(CheckoutView, self).get(request, *args, **kwargs)
        cart = self.get_object()
        if cart == None:
            return redirect("cart")
        new_order = self.get_order()
        user_checkout_id = request.session.get("user_checkout_id")
        if user_checkout_id != None:
            user_checkout = UserCheckout.objects.get(id=user_checkout_id)
            if new_order.billing_address == None or
new_order.shipping_address == None:
                return redirect("order_address")
            new_order.user = user_checkout
            new_order.save()
        return get_data

class CheckoutFinalView(CartOrderMixin, View):
    def post(self, request, *args, **kwargs):
        order = self.get_order()
        order_total = order.order_total
        nonce = request.POST.get("payment_method_nonce")
        if nonce:
            result = braintree.Transaction.sale({
                "amount": order_total,
                "payment_method_nonce": nonce,
                "billing": {
                    "postal_code": "%s" %(order.billing_address.zipcode),

                 },
                "options": {
                    "submit_for_settlement": True
                }
            })
            if result.is_success:
                #result.transaction.id to order
                order.mark_completed(order_id=result.transaction.id)
                messages.success(request, "Thank you for your order.")
                del request.session["cart_id"]
                del request.session["order_id"]
            else:
                #messages.success(request, "There was a problem with your
order.")
                messages.success(request, "%s" %(result.message))
                return redirect("checkout")

        return redirect("order_detail", pk=order.pk)

    def get(self, request, *args, **kwargs):
        return redirect("checkout")

*My orders app models.py:*

import braintree

if settings.DEBUG:
    braintree.Configuration.configure(braintree.Environment.Sandbox,
        merchant_id=settings.BRAINTREE_MERCHANT_ID,
        public_key=settings.BRAINTREE_PUBLIC,
        private_key=settings.BRAINTREE_PRIVATE)



class UserCheckout(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, null=True,
blank=True) #not required
    email = models.EmailField(unique=True) #--> required
    braintree_id = models.CharField(max_length=120, null=True, blank=True)

    def __unicode__(self): #def __str__(self):
        return self.email

    @property
    def get_braintree_id(self,):
        instance = self
        if not instance.braintree_id:
            result = braintree.Customer.create({
                "email": instance.email,
            })
            if result.is_success:
                instance.braintree_id = result.customer.id
                instance.save()
        return instance.braintree_id

    def get_client_token(self):
        customer_id = self.get_braintree_id
        if customer_id:
            client_token = braintree.ClientToken.generate({
                "customer_id": customer_id
            })
            return client_token
        return None


def update_braintree_id(sender, instance, *args, **kwargs):
    if not instance.braintree_id:
        instance.get_braintree_id


post_save.connect(update_braintree_id, sender=UserCheckout)




ADDRESS_TYPE = (
    ('billing', 'Billing'),
    ('shipping', 'Shipping'),
)

class UserAddress(models.Model):
    user = models.ForeignKey(UserCheckout)
    type = models.CharField(max_length=120, choices=ADDRESS_TYPE)
    street = models.CharField(max_length=120)
    city = models.CharField(max_length=120)
    state = models.CharField(max_length=120)
    zipcode = models.CharField(max_length=120)

    def __unicode__(self):
        return self.street

    def get_address(self):
        return "%s, %s, %s %s" %(self.street, self.city, self.state,
self.zipcode)


ORDER_STATUS_CHOICES = (
    ('created', 'Created'),
    ('paid', 'Paid'),
    ('shipped', 'Shipped'),
    ('refunded', 'Refunded'),
)


class Order(models.Model):
    status = models.CharField(max_length=120, choices=ORDER_STATUS_CHOICES,
default='created')
    cart = models.ForeignKey(Cart)
    user = models.ForeignKey(UserCheckout, null=True)
    billing_address = models.ForeignKey(UserAddress,
related_name='billing_address', null=True)
    shipping_address = models.ForeignKey(UserAddress,
related_name='shipping_address', null=True)
    shipping_total_price = models.DecimalField(max_digits=50,
decimal_places=2, default=5.99)
    order_total = models.DecimalField(max_digits=50, decimal_places=2, )
    order_id = models.CharField(max_length=20, null=True, blank=True)

    def __unicode__(self):
        return str(self.cart.id)

    class Meta:
        ordering = ['-id']

    def get_absolute_url(self):
        return reverse("order_detail", kwargs={"pk": self.pk})

    def mark_completed(self, order_id=None):
        self.status = "paid"
        if order_id and not self.order_id:
            self.order_id = order_id
        self.save()


def order_pre_save(sender, instance, *args, **kwargs):
    shipping_total_price = instance.shipping_total_price
    cart_total = instance.cart.total
    order_total = Decimal(shipping_total_price) + Decimal(cart_total)
    instance.order_total = order_total

pre_save.connect(order_pre_save, sender=Order)

*My orders views.py:*

class OrderDetail(DetailView):
    model = Order

    def dispatch(self, request, *args, **kwargs):
        try:
            user_check_id = self.request.session.get("user_checkout_id")
            user_checkout = UserCheckout.objects.get(id=user_check_id)
        except UserCheckout.DoesNotExist:
            user_checkout = UserCheckout.objects.get(user=request.user)
        except:
            user_checkout = None

        obj = self.get_object()
        if obj.user == user_checkout and user_checkout is not None:
            return super(OrderDetail, self).dispatch(request, *args,
**kwargs)
        else:
            raise Http404




class OrderList(ListView):
    queryset = Order.objects.all()

    def get_queryset(self):
        user_check_id = self.request.user.id
        user_checkout = UserCheckout.objects.get(id=user_check_id)
        return super(OrderList,
self).get_queryset().filter(user=user_checkout)




class UserAddressCreateView(CreateView):
    form_class = UserAddressForm
    template_name = "forms.html"
    success_url = "/checkout/address/"

    def get_checkout_user(self):
        user_check_id = self.request.session.get("user_checkout_id")
        user_checkout = UserCheckout.objects.get(id=user_check_id)
        return user_checkout

    def form_valid(self, form, *args, **kwargs):
        form.instance.user = self.get_checkout_user()
        return super(UserAddressCreateView, self).form_valid(form, *args,
**kwargs)



class AddressSelectFormView(CartOrderMixin, FormView):
    form_class = AddressForm
    template_name = "orders/address_select.html"


    def dispatch(self, *args, **kwargs):
        b_address, s_address = self.get_addresses()
        if b_address.count() == 0:
            messages.success(self.request, "Please add a billing address
before continuing")
            return redirect("user_address_create")
        elif s_address.count() == 0:
            messages.success(self.request, "Please add a shipping address
before continuing")
            return redirect("user_address_create")
        else:
            return super(AddressSelectFormView, self).dispatch(*args,
**kwargs)


    def get_addresses(self, *args, **kwargs):
        user_check_id = self.request.session.get("user_checkout_id")
        user_checkout = UserCheckout.objects.get(id=user_check_id)
        b_address = UserAddress.objects.filter(
                user=user_checkout,
                type='billing',
            )
        s_address = UserAddress.objects.filter(
                user=user_checkout,
                type='shipping',
            )
        return b_address, s_address


    def get_form(self, *args, **kwargs):
        form = super(AddressSelectFormView, self).get_form(*args, **kwargs)
        b_address, s_address = self.get_addresses()

        form.fields["billing_address"].queryset = b_address
        form.fields["shipping_address"].queryset = s_address
        return form

    def form_valid(self, form, *args, **kwargs):
        billing_address = form.cleaned_data["billing_address"]
        shipping_address = form.cleaned_data["shipping_address"]
        order = self.get_order()
        order.billing_address = billing_address
        order.shipping_address = shipping_address
        order.save()
        return  super(AddressSelectFormView, self).form_valid(form, *args,
**kwargs)

    def get_success_url(self, *args, **kwargs):
        return "/checkout/"

*Error I get when checking out is:*

Environment:


Request Method: GET
Request URL: http://localhost:8000/checkout/

Django Version: 1.8.5
Python Version: 2.7.9
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'blog',
 'products',
 'orders',
 'carts',
 'newsletter',
 'crispy_forms',
 'registration',
 'colorfield',
 'hitcount')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')


Traceback:
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\core\handlers\base.py"
in get_response
  132.                     response = wrapped_callback(request,
*callback_args, **callback_kwargs)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\views\generic\base.py"
in view
  71.             return self.dispatch(request, *args, **kwargs)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\views\generic\base.py"
in dispatch
  89.         return handler(request, *args, **kwargs)
File "C:\Users\Mudassar\dressikarepo\src\carts\views.py" in get
  188.         get_data = super(CheckoutView, self).get(request, *args,
**kwargs)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\views\generic\detail.py"
in get
  116.         context = self.get_context_data(object=self.object)
File "C:\Users\Mudassar\dressikarepo\src\carts\views.py" in get_context_data
  167.         context["order"] = self.get_order()
File "C:\Users\Mudassar\dressikarepo\src\orders\mixins.py" in get_order
  22.             new_order = Order.objects.create(cart=cart)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\models\manager.py"
in manager_method
  127.                 return getattr(self.get_queryset(), name)(*args,
**kwargs)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\models\query.py"
in create
  348.         obj.save(force_insert=True, using=self.db)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\models\base.py"
in save
  734.                        force_update=force_update,
update_fields=update_fields)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\models\base.py"
in save_base
  762.             updated = self._save_table(raw, cls, force_insert,
force_update, using, update_fields)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\models\base.py"
in _save_table
  846.             result = self._do_insert(cls._base_manager, using,
fields, update_pk, raw)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\models\base.py"
in _do_insert
  885.                                using=using, raw=raw)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\models\manager.py"
in manager_method
  127.                 return getattr(self.get_queryset(), name)(*args,
**kwargs)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\models\query.py"
in _insert
  920.         return query.get_compiler(using=using).execute_sql(return_id)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\models\sql\compiler.py"
in execute_sql
  974.                 cursor.execute(sql, params)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\backends\utils.py"
in execute
  79.             return super(CursorDebugWrapper, self).execute(sql,
params)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\backends\utils.py"
in execute
  64.                 return self.cursor.execute(sql, params)
File "C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\utils.py"
in __exit__
  97.                 six.reraise(dj_exc_type, dj_exc_value, traceback)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\backends\utils.py"
in execute
  64.                 return self.cursor.execute(sql, params)
File
"C:\Users\Mudassar\dressikarepo\lib\site-packages\django\db\backends\sqlite3\base.py"
in execute
  318.         return Database.Cursor.execute(self, query, params)

Exception Type: OperationalError at /checkout/
Exception Value: table orders_order has no column named order_id
...........

*My migrations table for orders shows:*

class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('carts', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='Order',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False,
auto_created=True, primary_key=True)),
                ('status', models.CharField(default=b'created',
max_length=120, choices=[(b'created', b'Created'), (b'paid', b'Paid'),
(b'shipped', b'Shipped'), (b'refunded', b'Refunded')])),
                ('shipping_total_price', models.DecimalField(default=5.99,
max_digits=50, decimal_places=2)),
                ('order_total', models.DecimalField(max_digits=50,
decimal_places=2)),
                ('order_id', models.CharField(max_length=20, null=True,
blank=True)),
            ],
            options={
                'ordering': ['-id'],
            },
        ),
        migrations.CreateModel(
            name='UserAddress',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False,
auto_created=True, primary_key=True)),
                ('type', models.CharField(max_length=120,
choices=[(b'billing', b'Billing'), (b'shipping', b'Shipping')])),
                ('street', models.CharField(max_length=120)),
                ('city', models.CharField(max_length=120)),
                ('state', models.CharField(max_length=120)),
                ('zipcode', models.CharField(max_length=120)),
            ],
        ),
        migrations.CreateModel(
            name='UserCheckout',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False,
auto_created=True, primary_key=True)),
                ('email', models.EmailField(unique=True, max_length=254)),
                ('braintree_id', models.CharField(max_length=120,
null=True, blank=True)),
                ('user', models.OneToOneField(null=True, blank=True,
to=settings.AUTH_USER_MODEL)),
            ],
        ),
        migrations.AddField(
            model_name='useraddress',
            name='user',
            field=models.ForeignKey(to='orders.UserCheckout'),
        ),
        migrations.AddField(
            model_name='order',
            name='billing_address',
            field=models.ForeignKey(related_name='billing_address',
to='orders.UserAddress', null=True),
        ),
        migrations.AddField(
            model_name='order',
            name='cart',
            field=models.ForeignKey(to='carts.Cart'),
        ),
        migrations.AddField(
            model_name='order',
            name='shipping_address',
            field=models.ForeignKey(related_name='shipping_address',
to='orders.UserAddress', null=True),
        ),
        migrations.AddField(
            model_name='order',
            name='user',
            field=models.ForeignKey(to='orders.UserCheckout', null=True),
        ),
    ]

*It creates a cart but isn't processing orders due to the error above.
Please advise*

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CANoUts4sptWyG7ayJgOZWe7S66L2_GuribOVj_TRii8VoKHokg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to