Hi all,

I have been battling with this issue for quite a long time and I haven't 
been able to find a solution to fix it. 

So, I have an E-commerce Project and The issue is related to the product 
Variations and the quantity related to it in the order summary page. 

Example with the sequence for my issue: 

1. From the product details I add to cart the item* White T-shirt*  after 
choosing the variations of *Small *Size
2. After adding the first item, I return to the product details page and 
add another *White T-shirt* but different size *Medium*

Now, this is what appears in my order summary:


   - *White T-shirt* with a size *Small *Quantity: 1
   - *White T-shirt *with a size *Medium *Quantity:1

When I change the quantity of item X size medium, this change is reflecting 
in item X size small which was chosen first.

To be like this:

   - *White T-shirt* with a size *Small *Quantity:2
   - *White T-shirt* with a size *Medium *Quantity:1

In the order summary, there are a plus and minus in the template to change 
the quantity.

I have recently understood that because there's no form in the template. 
The code that sends a POST request with form data to the add to cart view 
is not there, because item_var will always be an empty list so 
order_item.variation.add(*item_var) does nothing. I do not know how to add 
a POST request to this template.

in the template there is a URL to add-to-cart", but URLs are transmitted by 
GET, so the code after if request.method == 'POST': never hits. 
Furthermore, even if it would, the add_to_cart url knows nothing about 
variations cause it only gets item slugs.


Here is my models.py

class Item(models.Model):
    title = models.CharField(max_length=100)
    price = models.DecimalField(decimal_places=2, max_digits=100)


class VariationManager(models.Manager):
    def all(self):
        return super(VariationManager, self).filter(active=True)

    def sizes(self):
        return self.all().filter(category='size')

    def colors(self):
        return self.all().filter(category='color')

VAR_CATEGORIES = (
    ('size', 'size',),
    ('color', 'color',),
    ('package', 'package'),
)


class Variation(models.Model):
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    title = models.CharField(max_length=120)
    price = models.DecimalField(decimal_places=2, max_digits=100, null=True, 
blank=True)
    objects = VariationManager()


class OrderItem(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             on_delete=models.CASCADE)
    ordered = models.BooleanField(default=False)
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    quantity = models.IntegerField(default=1)
    variation = models.ManyToManyField(Variation)


Here are the views:

class OrderSummaryView(LoginRequiredMixin, View):
    def get(self, *args, **kwargs):

        try:
            order = Order.objects.get(user=self.request.user, ordered=False)
            context = {
                'object': order
            }
            return render(self.request, 'order_summary.html', context)
        except ObjectDoesNotExist:
            messages.warning(self.request, "You do not have an active order")
            return redirect("/")


@login_required
def add_to_cart(request, slug):
    item = get_object_or_404(Item, slug=slug)
    order_item_qs = OrderItem.objects.filter(
        item=item,
        user=request.user,
        ordered=False
    )
    item_var = []  # item variation
    if request.method == 'POST':
        for items in request.POST:
            key = items
            val = request.POST[key]
            try:
                v = Variation.objects.get(
                    item=item,
                    category__iexact=key,
                    title__iexact=val
                )
                item_var.append(v)
            except:
                pass

        if len(item_var) > 0:
            for items in item_var:
                order_item_qs = order_item_qs.filter(
                    variation__exact=items,
                )

    if order_item_qs.exists():
        order_item = order_item_qs.first()
        order_item.quantity += 1
        order_item.save()
    else:
        order_item = OrderItem.objects.create(
            item=item,
            user=request.user,
            ordered=False
        )
        order_item.variation.add(*item_var)
        order_item.save()

    order_qs = Order.objects.filter(user=request.user, ordered=False)
    if order_qs.exists():
        order = order_qs[0]
        # check if the order item is in the order
        if not order.items.filter(item__id=order_item.id).exists():
            order.items.add(order_item)
            messages.info(request, "This item quantity was updated.")
            return redirect("core:order-summary")
    else:
        ordered_date = timezone.now()
        order = Order.objects.create(
            user=request.user, ordered_date=ordered_date)
        order.items.add(order_item)
        messages.info(request, "This item was added to cart.")
        return redirect("core:order-summary")


@login_required
def remove_from_cart(request, slug):
    item = get_object_or_404(Item, slug=slug)
    order_qs = Order.objects.filter(
        user=request.user,
        ordered=False
    )
    if order_qs.exists():
        order = order_qs[0]
        # check if the order item is in the order
        if order.items.filter(item__slug=item.slug).exists():
            order_item = OrderItem.objects.filter(
                item=item,
                user=request.user,
                ordered=False
            )[0]
            order.items.remove(order_item)
            order_item.delete()
            messages.info(request, "This item was removed from your cart")
            return redirect("core:order-summary")

        else:
            messages.info(request, "This item was not in your cart")
            return redirect("core:product", slug=slug)
    else:
        messages.info(request, "You don't have an active order")
        return redirect("core:product", slug=slug)


@login_required
def remove_single_item_from_cart(request, slug):
    item = get_object_or_404(Item, slug=slug)
    order_qs = Order.objects.filter(
        user=request.user,
        ordered=False
    )
    if order_qs.exists():
        order = order_qs[0]
        # check if the order item is in the order
        if order.items.filter(item__slug=item.slug).exists():
            order_item = OrderItem.objects.filter(
                item=item,
                user=request.user,
                ordered=False
            )[0]
            if order_item.quantity > 1:
                order_item.quantity -= 1
                order_item.save()
            else:
                order.items.remove(order_item)
            messages.info(request, "This item quantity was updated")
            return redirect("core:order-summary")
        else:
            messages.info(request, "This item was not in your cart")
            return redirect("core:product", slug=slug)
    else:
        messages.info(request, "You do not have an active order")
        return redirect("core:product", slug=slug)


app_name = 'core'

urlpatterns = [
    path('', HomeView.as_view(), name='home'),
    path('order-summary/', OrderSummaryView.as_view(), name='order-summary'),
    path('product/<slug>/', ItemDetailView.as_view(), name='product'),
    path('add-to-cart/<slug>/', add_to_cart, name='add-to-cart'),
    path('remove-item-from-cart/<slug>/', remove_single_item_from_cart,
         name='remove-single-item-from-cart'),
    path('remove-from-cart/<slug>/', remove_from_cart, name='remove-from-cart'),
]


This is the template from the product details which is working perfectly 
fine: 

<form method="POST" action="{{ item.get_add_to_cart_url }}">
    {% csrf_token %}
    <input class="btn btn-primary btn-md my-2 p" type="submit" value="Add to 
cart">

    {% if object.variation_set.all %}

    {% if object.variation_set.sizes %}
<select class="form-control" name="size">
    {% for items in object.variation_set.sizes %}
    <option value="{{ items.title|lower }}">{{ items.title|capfirst }}</option>
    {% endfor %}
</select>
{% endif %}
{% endif %}
</form>


Here is the template which is not working Order Summary:


{% for order_item in object.items.all %}
<tr>
    <th scope="row">{{ forloop.counter }}</th>
    <td>{{ order_item.item.title }}</td>
    <td>
            {% if order_item.item.discount_price %}
                    <del>${{ order_item.item.price }}</del>
                {{ order_item.item.discount_price }}
            {% else %}
                ${{ order_item.item.price }}
            {% endif %}
    </td>
    <td>

    <a href="{% url 'core:remove-single-item-from-cart' order_item.item.slug 
%}"><i class="fas fa-minus mr-2"></a></i>
    {{ order_item.quantity }}
    <a href="{% url 'core:add-to-cart' order_item.item.slug %}"><i class="fas 
fa-plus ml-2"></a></i>

    </td>
    <td>
    {% if order_item.variation.all %}
    {% for variation in order_item.variation.all %}
    {{ variation.title|capfirst }}
    {% endfor %}
    {% endif %}


I really need some help in this issue 


-- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/46a33037-0e5a-4152-9c6d-36050bff29a2o%40googlegroups.com.

Reply via email to