Hi, everyone, I’m building a django ecommerce website based on john elder tutuorial ,
the project has a session for every user to add items for each user, and those session item quantities should appear on the cart icon in the navbar across all the pages of the websites, but for my project this is not working as it the cart quantity disappear on page reload, I have followed exactly the same steps but with no progress.
could anyone review my project and point out to the problem.
here is my project on github
MinaEmad2024/shubeik
and here are john elder project
flatplanet/Django-Ecommerce
Welcome @MinaEmad2024 !
You are more likely to attract attention to this issue if you provide a bit of a road map for the code. People are less likely to read through an entire project if they don’t have any real idea of where to look.
So I suggest you identify the files, functions, and models involved.
@KenWhitesell
thank you for your reply
here is project structure it contains 2 app (store, cart) + the main app
simply this is an e-commerce website with a navbar containing a cart icon
the cart app has a cart.py file contains A Cart class responsible for creating a cart session for each user like this
from store.models import Product
# from django.contrib.sessions.models import Session
class Cart():
def __init__(self, request):
self.session = request.session
# Get request
#self.request = request
# Get he current user sessionkey if exists
cart = self.session.get('session_key')
# k = k = Session.objects.get(pk=self.session.get('session_key'))
# print(k.get_decoded())
#if the user is new, no session key create one!
if 'session.key' not in request.session:
cart = self.session['session_key'] = {}
#Make sure the cart is available on all pages of the site
self.cart = cart
def add(self, product):
product_id = str(product.id)
#logic
if product_id in self.cart:
pass
else:
self.cart[product_id] = { 'price': str(product.price)}
self.session.modified = True
def __len__(self):
return len(self.cart)
def get_products(self):
#Get ids from cart
products_ids = self.cart.keys()
#use ids to lookup products in database model
products = Product.objects.filter(id__in=products_ids)
#return looked_up products
return products
and also has a context_processor.py file responsible for making the session available for all pages like this here
from .cart import Cart
# Create context processor for our cart so the car works on all pages of our site
def cart(request):
#return the default data from our cart
return {'cart': Cart(request)}
and this file is connected to the rest of the django strucure in the settings,py file like this
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'cart.context_processors.cart',
],
},
},
]
now I can add items to the cart session to be available across all pages with the number of items in the cart appears on the cart icon in the navbar through using ajax in the product.html file
and when adding a single product it works as expected in the same page but upon reloading the same page or routing to another page the session loses its content and the number in the cart icon returns to zero.
I wasn’t able to locate the source of such error especially I followed all the instructions in the tutorial.
here view.py in the cart app
from django.shortcuts import render, get_object_or_404
from .cart import Cart
from store.models import Product
from django.http import JsonResponse
# Create your views here.
def cart_summary(request):
cart = Cart(request)
cart_products = cart.get_products
return render(request, 'cart_summary.html', {"cart_products": cart_products})
def cart_add(request):
# get the cart
cart = Cart(request)
#test for post
if request.POST.get('action') == 'post':
#get stuff
product_id = int(request.POST.get('product_id'))
#lookup product in DB
product = get_object_or_404(Product, id=product_id)
#save to session
cart.add(product=product)
# get cart quantity
cart_quantity = cart.__len__()
#Return a response
#response = JsonResponse({'Product Name :': product.name })
response = JsonResponse({'qty' : cart_quantity})
return response
def cart_delete(request):
pass
def cart_update(request):
pass
and here is script I use to add individual product to the cart session
<script>
// check if a button presses
$(document).on('click', '#add-to-cart', function(e){
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url "cart_add" %}',
data: {
product_id: $('#add-to-cart').val(),
csrfmiddlewaretoken: '{{ csrf_token }}',
action:'post',
},
success: function(json){
console.log(json)
document.getElementById("cart_quantity").textContent = json.qty
},
error: function(xhr, errmsg, err){
}
});
})
</script>
Where would 'session.key'
be added to the session?
no, it should add ‘session_key’ to the session not adding ‘session.key’
Then why are you looking for 'session.key’
in the if
statement?
@KenWhitesell
You’ve got it, this is exactly the mistake
I did change session.key to session_key and now everything works fine.
thank you for your sincere help.
Now I’ll continue the work.
@KenWhitesell
honestly I’m not really understand how this line works,
self.cart = cart
could you please , explain how it works?
You’ve got two related lines of code where you only really need one.
Within the __init__
method, you’ve got the line:
cart = self.session.get('session_key')
This is creating a local variable within the scope of that method. That variable will no longer exist (for all practical purposes) once the function exits.
The second line, the line you are questioning:
self.cart = cart
Is assigning that local variable to a variable on the instance of the class. This means that as long as the class instance exists, you’ll have access to that variable.
These two lines can be combined:
self.cart = self.session.get('session_key')
There is no need to create that temporary assignment, other than to logically separate those two steps for teaching purposes.
If you’re not clear on the difference between cart
and self.cart
, then I suggest you read 9. Classes — Python 3.13.1 documentation, because understanding classes is a fundamental part of being able to use Django effectively.