sforkowany z mtyton/comfy
added possibility to remove product from cart
rodzic
20ea20fa79
commit
4a588bf8ea
|
@ -23,7 +23,9 @@ RUN apt-get update --yes --quiet && apt-get install --yes --quiet --no-install-r
|
|||
|
||||
# Install the project requirements.
|
||||
COPY requirements.txt /
|
||||
COPY requirements_dev.txt /
|
||||
RUN pip install -r /requirements.txt
|
||||
RUN pip install -r /requirements_dev.txt
|
||||
|
||||
# Use /app folder as a directory where the source code is stored.
|
||||
WORKDIR /app
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16">
|
||||
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6Z"/>
|
||||
<path d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1ZM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118ZM2.5 3h11V2h-11v1Z"/>
|
||||
</svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 553 B |
|
@ -51,7 +51,7 @@
|
|||
<script type="text/javascript" src="{% static 'js/jquery-3.6.4.min.js' %}"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.14.7/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="{% static 'bootstrap/js/bootstrap.bundle.min.js' %}"></script>
|
||||
|
||||
<script src="{% static 'js/cart.js' %}"></script>
|
||||
{% block extra_js %}
|
||||
{# Override this in templates to add extra javascript #}
|
||||
{% endblock %}
|
||||
|
|
|
@ -13,6 +13,8 @@ services:
|
|||
- DATABASE_URL
|
||||
env_file:
|
||||
- .env
|
||||
stdin_open: true
|
||||
tty: true
|
||||
db:
|
||||
image: postgres
|
||||
restart: always
|
||||
|
|
|
@ -2,3 +2,4 @@ FLAKE8>=6.0.0
|
|||
pre-commit>=3.3.1
|
||||
isort>=5.12
|
||||
black>=23.3.0
|
||||
ipdb==0.12.3
|
||||
|
|
|
@ -51,9 +51,9 @@ class SessionCart(BaseCart):
|
|||
self.validate_item_id(item_id)
|
||||
quantity = int(quantity)
|
||||
item_id = int(item_id)
|
||||
|
||||
if not self.session[settings.CART_SESSION_ID].get(item_id):
|
||||
if not self.session[settings.CART_SESSION_ID].get(str(item_id)):
|
||||
self.session[settings.CART_SESSION_ID][item_id] = quantity
|
||||
self.session.modified = True
|
||||
else:
|
||||
self.update_item_quantity(item_id, quantity)
|
||||
|
||||
|
@ -61,6 +61,7 @@ class SessionCart(BaseCart):
|
|||
self.validate_item_id(item_id)
|
||||
try:
|
||||
self.session[settings.CART_SESSION_ID].pop(item_id)
|
||||
self.session.modified = True
|
||||
except KeyError:
|
||||
# TODO - add logging
|
||||
...
|
||||
|
@ -68,7 +69,8 @@ class SessionCart(BaseCart):
|
|||
def update_item_quantity(self, item_id: int, change: int) -> None:
|
||||
self.validate_item_id(item_id)
|
||||
try:
|
||||
self.session[settings.CART_SESSION_ID][item_id] += change
|
||||
self.session[settings.CART_SESSION_ID][str(item_id)] += change
|
||||
self.session.modified = True
|
||||
except KeyError:
|
||||
# TODO - add logging
|
||||
self.add_item(item_id, change)
|
||||
|
|
|
@ -28,10 +28,10 @@ class CartProductAddSerializer(serializers.Serializer):
|
|||
|
||||
def validate_product_id(self, value):
|
||||
try:
|
||||
self.product = Product.obejcts.get(id=value)
|
||||
except Product.objects.DoesNotExist:
|
||||
Product.objects.get(id=value)
|
||||
except Product.DoesNotExist:
|
||||
raise serializers.ValidationError("Unable to add not existing product")
|
||||
return value
|
||||
|
||||
def save(self, cart):
|
||||
cart.add_item(self.product, self.validated_data["quantity"])
|
||||
cart.add_item(self.validated_data["product_id"], self.validated_data["quantity"])
|
||||
|
|
|
@ -4,10 +4,11 @@ $(document).on('click', '.add-to-cart-button', function(event) {
|
|||
event.preventDefault();
|
||||
const button = $(this);
|
||||
const formData = new FormData();
|
||||
const productID = $(this).data('product-id');
|
||||
const quantity = $('#quantity'+productID).val();
|
||||
const productID = parseInt($(this).data('product-id'));
|
||||
const quantity = parseInt($('#quantity'+productID).val());
|
||||
const addToCartURL = $(this).data('add-to-cart-url');
|
||||
const csrfToken = $(this).data('csrf-token');
|
||||
console.log(productID);
|
||||
formData.append('product_id', productID);
|
||||
formData.append('quantity', quantity); // Serialize the form data correctly
|
||||
button.prop('disabled', true);
|
||||
|
@ -107,15 +108,16 @@ $(document).on('click', '.add-to-cart-button', function(event) {
|
|||
const button = $(this);
|
||||
const productId = button.data('product-id');
|
||||
const csrfToken = button.data('csrf-token');
|
||||
|
||||
const url = button.data('remove-from-cart-url');
|
||||
$.ajax({
|
||||
type: 'DELETE',
|
||||
url: '/cart/item/' + parseInt(productId) + '/',
|
||||
type: 'POST',
|
||||
url: url,
|
||||
data: {"product_id": productId},
|
||||
headers: { 'X-CSRFToken': csrfToken },
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
alert(data.message);
|
||||
fetchCartItems(csrfToken);
|
||||
alert("Item has been removed");
|
||||
location.reload();
|
||||
},
|
||||
error: function() {
|
||||
alert("Error occurred while removing the item from the cart.");
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="{% static 'js/cart.js' %}"></script>
|
||||
|
||||
{% block content %}
|
||||
<section class="h-100">
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
{% load static %}
|
||||
|
||||
<div class="card rounded-3 mb-4">
|
||||
<div class="card-body p-4">
|
||||
<div class="row d-flex justify-content-between align-items-center">
|
||||
|
@ -27,7 +29,12 @@
|
|||
<h5 class="mb-0">{{item.product.price}} ZŁ</h5>
|
||||
</div>
|
||||
<div class="col-md-1 col-lg-1 col-xl-1 text-end">
|
||||
<a href="#!" class="text-danger"><i class="fas fa-trash fa-lg"></i></a>
|
||||
<a href="#!" class="text-danger remove-from-cart-button"
|
||||
data-product-id="{{item.product.id}}"
|
||||
data-csrf-token="{{csrf_token}}"
|
||||
data-remove-from-cart-url={% url "cart-action-remove-product" %}>
|
||||
<img src="{% static 'images/icons/trash.svg'%}" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
{% load static %}
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="{% static 'js/cart.js' %}"></script>
|
||||
{% load static %}
|
||||
|
||||
<div class="card h-100" style="width: 15rem;">
|
||||
<div class="card-header">{{item.title}}</div>
|
||||
|
@ -13,8 +11,10 @@
|
|||
</div>
|
||||
<div class="col text-end">
|
||||
<a href="#" class="btn btn-outline-success add-to-cart-button"
|
||||
data-product-id="{{ item.id }}"
|
||||
data-csrf-token="{{ csrf_token }}">
|
||||
data-product-id="{{item.id}}"
|
||||
data-csrf-token="{{csrf_token}}"
|
||||
data-add-to-cart-url={% url "cart-action-add-product" %}
|
||||
>
|
||||
<img src="{% static 'images/icons/cart.svg' %}" alt="Koszyk"/>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
{% extends 'base.html'%}
|
||||
{% load static %}
|
||||
<script src="{% static 'js/cart.js' %}"></script>
|
||||
|
||||
{% block content %}
|
||||
|
||||
|
|
|
@ -34,19 +34,27 @@ class CartActionView(ViewSet):
|
|||
# get cart items
|
||||
cart = SessionCart(self.request)
|
||||
items = cart.get_items()
|
||||
serialzier = CartProductSerializer(instance=items, many=True)
|
||||
return Response(serialzier.data)
|
||||
serializer = CartProductSerializer(instance=items, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@action(detail=False, methods=["post"])
|
||||
def add_product(self, request):
|
||||
cart = SessionCart(self.request)
|
||||
serializer = CartProductAddSerializer(data=request.POST)
|
||||
if serializer.is_valid():
|
||||
if not serializer.is_valid():
|
||||
return Response(serializer.errors, status=400)
|
||||
serializer.save(cart)
|
||||
|
||||
items = cart.get_items()
|
||||
serialzier = CartProductSerializer(instance=items, many=True)
|
||||
return Response(serialzier.data, status=201)
|
||||
serializer = CartProductSerializer(instance=items, many=True)
|
||||
return Response(serializer.data, status=201)
|
||||
|
||||
# TODO - same for remove product
|
||||
@action(detail=False, methods=["post"])
|
||||
def remove_product(self, request):
|
||||
cart = SessionCart(self.request)
|
||||
product_id = request.POST.get("product_id")
|
||||
cart.remove_item(product_id)
|
||||
|
||||
items = cart.get_items()
|
||||
serializer = CartProductSerializer(instance=items, many=True)
|
||||
return Response(serializer.data, status=201)
|
||||
|
|
Ładowanie…
Reference in New Issue