Django, кнопка +-1, js

Я пишу сайт для бронирования билетов в кино. В нем есть корзина. Я хочу реализовать кнопки + и - для добавления/удаления одного билета в корзине для сеанса в кино. Я еще плохо разбираюсь в AJAX и js, поэтому не понимаю, что не так. модели:

from django.db import models
from users.models import SiteUser
import uuid


class BaseModel(models.Model):
    uid = models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True)
    created_at = models.DateField(auto_now_add=True)
    updated_at = models.DateField(auto_now_add=True)

    class Meta:
        abstract = True


class MovieCategory(BaseModel):
    category_name = models.CharField(max_length=100)


class Movie(BaseModel):
    category = models.ForeignKey(MovieCategory, on_delete=models.CASCADE, related_name="pizzas")
    movie_name = models.CharField(max_length=100)
    price = models.IntegerField(default=100)
    images = models.ImageField(max_length=500)


class Cart(BaseModel):
    user = models.ForeignKey(SiteUser, null=True, blank=True, on_delete=models.SET_NULL, related_name="carts")
    is_paid = models.BooleanField(default=False)


class CartItems(BaseModel):
    cart = models.ForeignKey(Cart, on_delete=models.CASCADE, related_name="cart_items")
    movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
    quantity = models.IntegerField(default=1)

Просмотров:

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from .models import *
from .forms import *

def home(request):
    movies = Movie.objects.all()
    context = {'movies': movies}
    return render(request, "home.html", context)


@login_required(login_url="/login/")
def add_cart(request, movie_uid):
    user = request.user
    movie_obj = Movie.objects.get(uid=movie_uid)
    cart, _ = Cart.objects.get_or_create(user=user, is_paid=False)
    cart_item, created = CartItems.objects.get_or_create(cart=cart, movie=movie_obj)
    if not created:
        cart_item.quantity += 1
        cart_item.save()

    return redirect('/')


@login_required(login_url='/login/')
def cart(request):
    carts = Cart.objects.get(is_paid=False, user=request.user)
    context = {'carts': carts}
    return render(request, "cart.html", context)


@login_required(login_url='/login/')
def remove_cart_item(request, cart_item_uid):
    try:
        CartItems.objects.get(uid=cart_item_uid).delete()
        return redirect('/cart/')
    except Exception as e:
        print(e)


from django.views.decorators.http import require_POST


@require_POST
@login_required(login_url='/login/')
def update_cart_item_quantity(request, cart_item_uid):
    try:
        cart_item = CartItems.objects.get(uid=cart_item_uid)
        print(cart_item)
        new_quantity = int(request.POST.get('quantity'))
        if new_quantity < 0 or new_quantity > 20:
            return JsonResponse({'success': False, 'error': 'Invalid quantity'})

        cart_item.quantity = new_quantity
        cart_item.save()  # Сохраняем изменения в базе данных

        return JsonResponse({'success': True})
    except CartItems.DoesNotExist:
        print('1')
        return JsonResponse({'success': False, 'error': 'Cart item does not exist'}, status=404)
    except Exception as e:
        print('2')
        return JsonResponse({'success': False, 'error': 'An error occurred while updating cart item quantity'},
                            status=500)


Урлы:

from django.urls import path
from .views import *
from django.conf.urls.static import static
from django.conf import settings
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

urlpatterns = [
    path('', home, name='home'),
    path('cart/', cart, name='cart'),
    path('remove_cart_item/<cart_item_uid>', remove_cart_item, name='remove_cart'),
    path('add_cart/<movie_uid>', add_cart, name='add_cart'),
    path('update_cart_item_quantity/<cart_item_uid>/', update_cart_item_quantity, name='update_cart_item_quantity'),


]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

urlpatterns += staticfiles_urlpatterns()

cart.html:

{% extends "base.html" %}

{% load static %}
{% load filters %}
{% block start %}
<style>

</style>
<div class="container card shadow-lg mt-5 ">
    <table class="table">
        <thead>
            <tr>
                <th scope="col">Номер</th>
                <th scope="col">Отмена покупки</th>
                <th scope="col">Название</th>
                <th scope="col">Цена</th>
                <th scope="col">Кол-во</th>
            </tr>
        </thead>
        <tbody>
            {% for cartItems in carts.cart_items.all %}
            <tr>
                <th scope="row">{{forloop.counter}}</th>
                <td><a href="{% url 'remove_cart' cartItems.uid %}" class="btn btn-danger">Удалить</a>
                </td>
                <td>
                    <h5>{{cartItems.movie.movie_name}}</h5>
                </td>
                    <td id="total_price_{{ cartItems.uid }}">{{ cartItems.quantity|mul:cartItems.movie.price }}</td>

                <td>
                    {% csrf_token %}
                    <button onclick="updateCartItem('{{ cartItems.uid }}', {{ cartItems.movie.price }}, -1)">-</button>
                    <input type="number" id="quantity_{{ cartItems.uid }}" min="0" max="20" value="{{ cartItems.quantity }}">
                    <button onclick="updateCartItem('{{ cartItems.uid }}', {{ cartItems.movie.price }}, 1)">+</button>
                </td>
            </tr>
            {% endfor %}

            <tr>
                <th scope="col"></th>
                <td></td>
                <td></td>
                <td></td>
            </tr>
 
        </tbody>
    </table>
</div>
{% endblock %}

фильтры:

from django import template

register = template.Library()

@register.filter
def mul(value, arg):
    return value * arg

script.js:

function getCookie(name) {
  let cookieValue = null;
  if (document.cookie && document.cookie !== '') {
      const cookies = document.cookie.split(';');
      for (let i = 0; i < cookies.length; i++) {
          const cookie = cookies[i].trim();
          if (cookie.substring(0, name.length + 1) === (name + '=')) {
              cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
              break;
          }
      }
  }
  return cookieValue;
}

function updateCartItem(cartItemId, moviePrice, increment) {
  console.log('Cart item ID:', cartItemId); // Добавьте эту строку
  const quantityElement = document.querySelector(`#quantity_${cartItemId}`);
  let quantity = parseInt(quantityElement.value);
  quantity += increment;
  if (quantity < 0) {
      quantity = 0;
  }
  quantityElement.value = quantity;

  // Обновляем общую стоимость за билеты
  const totalPriceElement = document.querySelector(`#total_price_${cartItemId}`);
  const totalPrice = quantity * moviePrice;
  totalPriceElement.innerText = totalPrice;

  // Отправляем AJAX-запрос на сервер для обновления количества билетов
  updateCartQuantity(cartItemId, quantity);
}


function updateCartQuantity(cartItemId, quantity) {
  fetch(`/update_cart_item_quantity/${cartItemId}/`, {
      method: 'POST',
      headers: {
          'Content-Type': 'application/json',
          'X-CSRFToken': getCookie('csrftoken')
      },
      body: JSON.stringify({'quantity': quantity})
  })
  .then(response => {
      if (response.ok) {
          return response.json();
      } else {
          console.error(`Failed to update cart quantity. Server responded with status ${response.status}`);
          throw new Error(`Failed to update cart quantity. Server responded with status ${response.status}`);
      }
  })
  .then(data => {
      // Обработка успешного ответа, если нужно
  })
  .catch(error => {
      console.error('Error:', error);
  });
}

Я пытался переписать функции update_cart_item_quantity и AJAX в файле scripts.py, но ничего не выходит

Вернуться на верх