Как сохранить продукты на моем сайте Django Ecommerce

Я пытаюсь реализовать функцию на моем Django ecommerce сайте, где пользователь может сохранить желаемый продукт после нажатия на кнопку на странице детализации продукта -

<div class="me-3 text-white" onclick="saveProduct({{ product.id }})">
                                        <i class="bi bi-balloon-heart"></i>
                                    </div>

Это мой models.py -

class UserActivity(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    timestamp = models.DateTimeField(default=timezone.now)
    saved = models.BooleanField(default=False)  # a boolean field to track whether the product is saved by the user

    class Meta:
        ordering = ['-timestamp']

Это мой ecommerce/views.py -

@require_POST
@login_required
def save_product(request):
    if request.headers.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest':
        product_id = request.POST.get('product_id')
        product = get_object_or_404(Product, pk=product_id)

        # Check if the user has already saved the product
        user_activity, created = UserActivity.objects.get_or_create(user=request.user, product=product)
        if created:
            user_activity.saved = True
            user_activity.save()
            return JsonResponse({'status': 'success'})
        else:
            return JsonResponse({'status': 'error', 'message': 'Product already saved'}, status=400)
    else:
        return JsonResponse({'status': 'error', 'message': 'Invalid request'}, status=400)

вот мой ecommerce/urls.py -

app_name = 'ecommerce'

path('save_product/', views.save_product, name='save_product'),

Это мой accounts/views.py для отображения сохраненных продуктов -

@login_required
def saved_items(request):
    current_path = resolve(request.path_info).url_name

    saved_products = UserActivity.objects.filter(user=request.user, saved=True).select_related('product')

    return render(request, 'accounts/saved_items.html', {'current_path': current_path,
                                                         'saved_products': saved_products})

Это мой файл saved_items.html для отображения сохраненных продуктов -

{% for user_activity in saved_products %}
                <div class="border p-3 mb-2">     
                    <div class="row">
                        <div class="col-md-3">
                            <img src="{{ user_activity.product.image.url }}" alt="{{ user_activity.product.name }}" class="top-selling-image img-fluid">
                        </div>
    
                        <!-- Column for product details -->
                        <div class="col-md-7 d-flex flex-column justify-content-between">
                            <div class="product-name"> {{ user_activity.product.name }} </div>
                            <div class="">
                                <div class="text-white">N&nbsp; {{ user_activity.product.formatted_price }} </div>
                                <div class="d-flex">
                                    <div class="slashed-price text-white fs-6" style="text-decoration: line-through; font-size: 13px;">N {{ user_activity.product.discount_percentage }} </div>
                                <span class="badge bg-danger ms-2 fs-6">{{ user_activity.product.discount_percentage }} %</span>
                                </div>
                            </div>
                        </div>
    
                        <!-- Column for BUY AND REMOVE -->
                        <div class="col-md-2 d-flex flex-column justify-content-between ms-auto">
                            <a href="" class="btn btn-primary mt-2 mb-2" style="width: 100%;">BUY NOW</a>
                            <div><a href="" class="text-decoration-none text-primary">
                                <i class="bi bi-trash me-2"></i>REMOVE</a></div>
                        </div>
                    </div>
                </div>
                {% endfor %}

Это мой javascript для сохранения продукта с помощью AJAX -

<script type="text/javascript">
    // Function to save the product
    function saveProduct(productId) {
        console.log("clicked");

        // Create a new XMLHttpRequest object
        var xhr = new XMLHttpRequest();

        // Define the request parameters
        xhr.open('POST', '{% url "ecommerce:save_product" %}', true);
        xhr.setRequestHeader('Content-Type', 'application/json');
        
        // Define the data to be sent
        var data = 'product_id=' + productId + '&csrfmiddlewaretoken=' + '{{ csrf_token }}';
        

        // Define the onload callback function
        xhr.onload = function() {
            if (xhr.status >= 200 && xhr.status < 300) {
                var response = JSON.parse(xhr.responseText);
                console.log("AJAX request successful");
                if (response.status === 'success') {
                    alert('Product saved successfully!');
                } else {
                    alert('Error: ' + response.message);
                }
            } else {
                console.error("AJAX request failed:", xhr.statusText);
                alert('An error occurred while saving the product.');
            }
        };

        // Define the onerror callback function
        xhr.onerror = function() {
            console.error("AJAX request failed:", xhr.statusText);
            alert('An error occurred while saving the product.');
        };

        // Send the request
        xhr.send(data);
    }
</script>

после попытки сохранить продукт, нажав на иконку с воздушным сердечком, я получаю сообщение -

An error occurred while saving the product.

и в консоли браузера у меня -

    clicked
:8000/save_product/:1 
        
      
        
        
      
        
      
       
        
       Failed to load resource: the server responded with a status of 403 (Forbidden)
(index):378 
        
       AJAX request failed: Forbidden

Что я делаю не так?

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