Django: Добавление кнопки "Минус корзина" с помощью JQuery

Мои модели:

class Cart(models.Model):
    cart_id = models.CharField(max_length=255, blank=True)
    date_added = models.DateField(auto_now_add=True)

    class Meta:
        verbose_name_plural = 'Cart'

    def __str__(self):
        return self.cart_id


class CartItem(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
    quantity = models.IntegerField()
    is_active = models.BooleanField(default=True)

    def total(self):
        return self.product.price * self.quantity

    def __str__(self):
        return self.product

Мои взгляды:

def _cart_id(request):
    cart_id = request.session.session_key
    if not cart_id:
        cart_id = request.session.create()
    return cart_id


def add_to_cart(request, product_id):
    product = Product.objects.get(id=product_id)
    try:
        my_cart = Cart.objects.get(cart_id=_cart_id(request))
        my_cart.save()
    except ObjectDoesNotExist:
        my_cart = Cart.objects.create(
            cart_id=_cart_id(request),
        )
        my_cart.save()

    try:
        cart_item = CartItem.objects.get(product=product, cart=my_cart)
        cart_item.quantity += 1
        cart_item.save()
    except ObjectDoesNotExist:
        cart_item = CartItem.objects.create(
            product=product,
            cart=my_cart,
            quantity=1,
        )
        cart_item.save()
    return redirect('cart')


def cart(request, sub_total=0, quantity=0, cart_items=None, sale_tax=0):
    try:
        current_cart = Cart.objects.get(cart_id=_cart_id(request))
        cart_items = CartItem.objects.filter(cart=current_cart, is_active=True)
        for item in cart_items:
            sub_total += (item.product.price * item.quantity)
            quantity += item.quantity
        sale_tax = round((7 * sub_total)/100, 2)
    except ObjectDoesNotExist:
        pass
    context = {
        'sub_total': sub_total,
        'quantity': quantity,
        'cart_items': cart_items,
        'sale_tax': sale_tax,
        'grand_total': sale_tax + sub_total,
    }
    return render(request, 'cart.html', context)

Моя часть шаблона:

<tbody>
                                {% for item in cart_items %}
                                    <tr>
                                        <td class="product-thumbnail"><a href="{{ item.product.get_url }}"><img src="{{ item.product.image_1.url }}" alt=""></a></td>
                                        <td class="product-name"><a href="{{ item.product.get_url }}">{{ item.product.product_name }}</a></td>
                                        <td class="product-price"><span class="amount">${{ item.product.price }}</span></td>
                                        <td class="product-quantity">
                                            <div class="cart-plus-minus"><input type="text" value="{{ item.quantity }}" /></div>
                                        </td>
                                        <td class="product-subtotal"><span class="amount">${{ item.total }}</span></td>
                                        <td class="product-remove"><a href="#"><i class="fa fa-times"></i></a></td>
                                    </tr>
                                {% endfor %}
                                </tbody>

Мой JQuery:

$(".cart-plus-minus").append('<div class="dec qtybutton">-</div><div class="inc qtybutton">+</div>');
    $(".qtybutton").on("click", function () {
        var $button = $(this);
        var oldValue = $button.parent().find("input").val();
        if ($button.text() == "+") {
            var newVal = parseFloat(oldValue) + 1;
        } else {
            // Don't allow decrementing below zero
            if (oldValue > 0) {
                var newVal = parseFloat(oldValue) - 1;
            } else {
                newVal = 0;
            }
        }
        $button.parent().find("input").val(newVal);
    });

Я не специалист по JQuery, и поэтому я запутался в том, как обновить общую цену товара плюс или минус, когда покупатель нажимает кнопку плюс или минус - что JQuery возьмет на себя. В Django мой urlpatterns для корзины выглядит так:

urlpatterns = [
    path('', views.cart, name='cart'),
    path('add_to_cart/<int:product_id>/', views.add_to_cart, name='add_to_cart'),
]

Это означает, что если клиент нажимает на знак минус или плюс, количество товара в корзине должно увеличиться или уменьшиться на единицу - что мне нужно, так это чтобы знак плюс перенаправлял клиента на представление add_to_cart, которое уже закодировано, и это представление автоматически перенаправляло клиента обратно в корзину для обновления количества товара в корзине. Как мне на самом деле достичь этого в JQuery части кода, которую я разместил? Это должен быть именно тот кусочек кода JQuery, который я разместил, поскольку он поставляется вместе с шаблоном. В Django, в любом обычном шаблоне, это должно быть легко сделано следующим образом:

<a href="{% url 'add_to_cart' item.product.id %}" class="btn btn-light" type="button" id="button-minus"> <i class="fa fa-plus"></i></a>

Но как это сделать с помощью JQuery?

Я нашел ответ и заставил его работать. Тем не менее, теперь меня беспокоит вопрос безопасности XSS-атак. Безопасно ли писать код так, как я только что сделал, чтобы решить свою проблему?

Часть шаблона:

<div class="cart-plus-minus"><input type="text" value="{{ item.quantity }}"/>
                                            <input type="hidden" id="Url" data-url="{% url 'add_to_cart' item.product.id %}" />
                                            </div>

порция jQuery:

<script>
  // // // // ////////////////////////////////////////////////////
  // // // // // 21. Cart Plus Minus Js

  $(".cart-plus-minus").append(
    '<div class="dec qtybutton">-</div><div class="inc qtybutton">+</div>'
  );
  $(".qtybutton").on("click", function () {
    var $button = $(this);
    var oldValue = $button.parent().find("input").val();
    if ($button.text() == "+") {
      var newVal = parseFloat(oldValue) + 1;
      window.location.href = $("#Url").attr("data-url")   
    } else {
      // Don't allow decrementing below zero
      if (oldValue > 0) {
        var newVal = parseFloat(oldValue) - 1;
      } else {
        newVal = 0;
      }
    }
    $button.parent().find("input").val(newVal);
  });
    </script>

Часть, которую я исправил и она теперь работает, находится там, где:

window.location.href = $("#Url").attr("data-url")

Теперь мне интересно, будет ли это уязвимостью безопасности, если это исправление будет введено? Согласно документации Django:

json_script¶ Безопасный вывод объекта Python в виде JSON, завернутого в тег, готовый для использования с JavaScript.

.

Аргумент: HTML "id" тега.

Например:

{{ value|json_script: "hello-data" }} Если value - это словарь {'hello': 'world'}, то вывод будет следующим:

{ "hello": "world"}

Доступ к полученным данным можно получить в JavaScript следующим образом:

const value = JSON.parse(document.getElementById('hello-data').textContent); XSS-атаки смягчаются путем экранирования символов "<", ">" и "&". Например, если значение имеет вид {'hello': 'world&'}, будет выведено следующее:

{"hello": "world\\u003C/script\\u003E\\u0026amp;"}

Это совместимо со строгой политикой безопасности содержимого, которая запрещает выполнение сценариев на странице. Он также поддерживает чистое разделение между пассивными данными и исполняемым кодом.

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