Hi can you please help me with this problem. I have this code:
models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=255)
price = models.DecimalField(max_digits=10, decimal_places=2)
class Cart(models.Model):
products = models.ManyToManyField(Product, through='CartItem')
@property
def total_price(self):
return sum(item.product.price * item.quantity for item in self.cartitem_set.all())
class CartItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=1)
views.py
from django.shortcuts import render, redirect, get_object_or_404
from .models import Product, Cart, CartItem
def product_list(request):
products = Product.objects.all()
# Retrieve or create a cart ID in the session
cart_id = request.session.get('cart_id')
cart, created = Cart.objects.get_or_create(id=cart_id)
# Pass the cart items to the template context
cart_items = CartItem.objects.filter(cart=cart)
total_items_in_cart = sum(item.quantity for item in cart_items)
total_price = cart.total_price
for item in cart_items:
item.subtotal = item.product.price * item.quantity
context = {'products': products,
'cart_items': cart_items,
'total_items_in_cart': total_items_in_cart,
'total_price': total_price}
return render(request, 'product_list.html', context )
def add_to_cart(request, product_id):
product = get_object_or_404(Product, id=product_id)
cart_id = request.session.get('cart_id')
cart, created = Cart.objects.get_or_create(id=cart_id)
# Check if the product is already in the cart
cart_item, item_created = CartItem.objects.get_or_create(product=product, cart=cart)
if not item_created:
# If the product is already in the cart, update the quantity
cart_item.quantity += 1
cart_item.save()
# Update session with cart ID
request.session['cart_id'] = cart.id
request.session.save()
return render (request, 'cart_items_partial.html')
urls.py
from django.contrib import admin
from django.urls import path
from cart.views import product_list, add_to_cart, view_cart, decrease_item, remove_item, increase_item
urlpatterns = [
path('products/', product_list, name='product_list'),
path('add_to_cart/<int:product_id>/', add_to_cart, name='add_to_cart')
]
templates/product_list.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Product page</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/[email protected]/dist/htmx.js"></script>
</head>
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' class="mx-auto w-4/5 grid grid-cols-2 gap-5">
<div>
{% for product in products %}
<h3>{{ product.name }}</h3>
<p>Price: ${{ product.price }}</p>
<button hx-post="{% url 'add_to_cart' product.id %}" hx-target="#cart" hx-swap="innerHTML">Add to Cart</button>
<hr>
{% endfor %}
</div>
<!-- Cart -->
<div class="bg-blue-200 py-10 pl-5 rounded-xl">
<h2>Your Cart</h2>
<p>Total Items: {{ total_items_in_cart }}</p>
<div id="cart">
{% include "cart_items_partial.html" %}
</div>
<p>Total: ${{ total_price }}</p>
<a href="{% url 'view_cart' %}">View Cart</a>
</div>
</body>
</html>
templates/cart_items_partial.html
{% for item in cart_items %}
<div class="bg-red-200 rounded-xl my-2 mr-2">
<p>{{ item.product.name }} ({{ item.quantity }} x {{ item.product.price }}) = {{ item.subtotal }}</p>
</div>
{% endfor %}
when not using htmx and substitute button with
<a href="{% url 'add_to_cart' product.id %}"> Add to Cart</a>
and in views.py add to cart function:
return redirect('product_list')
everithing work just fine
Can you please help me implement HTMX to this project?
Thanks.
I tried code above with different hx-swap values like beforeend or outerHTML .
I expect the add to cart function to work like without HTMX but with no refresh of the page.