How can save session of shopping cart data after logout, so the user can find them when login again in Django?

一个人想着一个人 提交于 2020-06-01 06:20:53

问题


I am working on e-commerce website using Django, I'm working on the shopping cart it's implemented using sessions and it's currently working fine, except one problem when the authenticated user logout from website, and login again , all data on cart lost. How can save session of shopping cart data after logout, so the user can find them when login again?

my cart app files are:

1) cart.py

    from decimal import Decimal
    from django.conf import settings
    from shop.models import Product
    from coupons.models import Coupons

    class Cart(object):
    """docstring for Cart"""
    def __init__(self, request):
    """initalize the cart"""
       self.session = request.session
       cart = self.session.get(settings.CART_SESSION_ID)

       if not cart:
           cart = self.session[settings.CART_SESSION_ID] = {}
       self.cart = cart
       self.coupon_id = self.session.get('coupon_id')


   def add(self,product,quantity=1,update_quantity=False):
       product_id = str(product.id)
       if product_id not in self.cart:
           self.cart[product_id] = {'quantity':0,'price':str(product.price)}

       if update_quantity:
           self.cart[product_id]['quantity'] = quantity

       else:
           self.cart[product_id]['quantity'] += quantity

       self.save()

   def save(self):
       self.session[settings.CART_SESSION_ID] = self.cart
       self.session.modified = True

   def remove(self,product):
       product_id = str(product.id)
       if product_id in self.cart:
          del self.cart[product_id]
          self.save()

   def __iter__(self):
       product_ids = self.cart.keys()
       products = Product.objects.filter(id__in=product_ids)

       for product in products:
          self.cart[str(product.id)]['product'] = product

       for item in self.cart.values():
          item['price'] = Decimal(item['price'])
          item['total_price'] = item['price'] *  item['quantity']
          yield item

   def __len__(self):
       return sum(item['quantity'] for item in self.cart.values())

   def get_total_price(self):
       return sum(Decimal(item['price']) * item['quantity'] for item in self.cart.values())


   def clear(self):
       del self.session[settings.CART_SESSION_ID]
       self.session.modified = True

   @property
   def coupon(self):
       if self.coupon_id:
          return Coupons.objects.get(id=self.coupon_id)
       return None

   def get_discount(self):
       if self.coupon:
          return (self.coupon.discount / Decimal('100')) * self.get_total_price()
       return Decimal('0')

   def get_total_price_after_discount(self):
       return self.get_total_price() - self.get_discount()

2) views.py

   from django.shortcuts import render,redirect,get_object_or_404
   from django.views.decorators.http import require_POST
   from shop.models import Product
   from .cart import Cart
   from .forms import CartAddProductForm
   from coupons.forms import CouponApplyForm

   # Create your views here.

   @require_POST
   def cart_add(request,product_id):
      cart = Cart(request)
      product = get_object_or_404(Product,id=product_id)
      form = CartAddProductForm(request.POST)
      if form.is_valid():
         cd = form.cleaned_data
         cart.add(
            product=product,
            quantity=cd['quantity'],
            update_quantity=cd['update']
            )
      return redirect('cart_detail')

   def cart_remove(request,product_id):
      cart = Cart(request)
      product = get_object_or_404(Product,id=product_id)
      cart.remove(product)
      return redirect('cart_detail')

   def cart_detail(request):
      cart = Cart(request)
      for item in cart:
          item['update_quantity_form'] = CartAddProductForm(initial={'quantity':item['quantity'],'update':True})

      coupon_apply_form = CouponApplyForm()

      return render(request,'cart_detail.html',context = {'cart':cart,'coupon_apply_form':coupon_apply_form})

3) form.py

   from django import forms

   PRODUCT_QUANTITY_CHOICES = [(i,str(i)) for i in range(1,21)]

   class CartAddProductForm(forms.Form):
       # Define form fields here
       quantity = forms.TypedChoiceField(choices=PRODUCT_QUANTITY_CHOICES,coerce=int)
       update = forms.BooleanField(required=False,initial=False,widget=forms.HiddenInput)

4) cart_detail.html

   {% extends "base.html" %}
   {% load static %}
   {% block title_ %}
       Your Shopping Cart
   {% endblock title_ %}
   {% block breadcrumb %}
     <li class="breadcrumb-item active"><a href="{% url 'index'%}">Flowers Website</a></li>

   {% endblock %}
   {% block content %}

    <div class="container">

<div class="row">

  <div class="col-sm-12 col-lg-12 col-md-12">
<table>

    <thead class='t-head'>
        <h1>Your Shopping Cart</h1>
        <tr>
            <th>Image</th>
            <th>Product</th>
            <th>Quantity</th>
            <th>Remove</th>
            <th>Unit Price</th>
            <th>Price</th>
        </tr>
    </thead>
    <tbody>
        {% if cart %}
            {% for item in cart %}
                {% with  product=item.product %}
                    <tr>
                        <td>
                            <a href="{{ product.get_absolute_url }}">
                                <img src='
                                        {% if product.image %}
                                            {{ product.image.url }}
                                        {% else %}
                                            #
                                        {% endif %}'
                                     width="100px">
                            </a>

                        </td>
                        <td>{{product.name}}</td>
                        <td>
                            <form method="post" action="{% url 'cart_add' product.id %}">
                                {% csrf_token %}
                                {{item.update_quantity_form.quantity}}
                                {{item.update_quantity_form.update}}
                                <input type="submit" value="Update">
                            </form>
                        </td>
                        <td>
                            <a href="{% url 'cart_remove' product.id%}">
                                Remove
                            </a>
                        </td>
                        <td>
                            {{item.price}}
                        </td>
                        <td>
                            {{item.total_price}}
                        </td>
                    </tr>

                {% endwith %}
            {% endfor %}
        {% else %}
            <tr>
                <td colspan="4" style="width:100%;text-align:center;">there is no product !</td>
            </tr>
        {% endif %}

            {% if cart.coupon %}
                <tr class="gray">
                    <td>Subtotal</td>
                    <td colspan="4"></td>
                    <td class="num"> {{cart.get_total_price}}</td>
                </tr>
                <tr class="gray2">
                    {% block trans   %}
                        {% with code=cart.coupon.code discount=cart.coupon.discount%}
                            <td colspan="2">"{{code}}" coupon ({{discount}})% off</td>
                        {% endwith %}
                    {% endblock trans %}
                    <td colspan="3"></td>
                    <td class="num neg"> - ${{cart.get_discount|floatformat:"2"}}</td>
                </tr>
            {% endif %}
            <tr class="total">
                <td>Total</td>
                <td colspan="4"></td>
                <td class="num">${{cart.get_total_price_after_discount|floatformat:"2"}}.    </td>
            </tr>
    </tbody>
</table>
<div class="divo">
    <p>
        Apply a coupon
    </p>
    <form action="{% url 'coupon_apply' %}" method="post">
        {{coupon_apply_form}}
        {% csrf_token %}
        <input class="btn apply-button" type="submit" value="apply" >

    </form>
    <p class="text-right">
    <a href="{% url 'index' %}">Continu shopping</a>
    <a href="{% url 'orders:order_create' %}">Checkout</a>
    </p>
  </div>
  </div>
  </div>
 </div>
 {% endblock content %}

5) url.py

    from django.urls import path
    from . import views


    urlpatterns=[
       path('cart_detail/',views.cart_detail,name='cart_detail'),
       path('add/<product_id>/',views.cart_add,name='cart_add'),
       path('remove/<product_id>/',views.cart_remove,name='cart_remove'),
    ]

@John Meinken, I faced the same problem:

How to save and restore session data across logout/relogin in Django?

and your solution may solve my problem but, can you please explain it more for me , where should I create this table? and where should I used this functions ? for example my project contine many apps (accounts, shop,cart,orders)

Thanks in advance.

来源:https://stackoverflow.com/questions/62048726/how-can-save-session-of-shopping-cart-data-after-logout-so-the-user-can-find-th

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!