Я хотел создать 5-звездочную рейтинговую систему на django, но постоянно возникает эта ошибка:

я проверил с документом django и Но моя проблема не была решена [08/Feb/2023 15:57:18] "POST /courses/2/learning-django HTTP/1.1" 403 2506 ошибка: Forbidden (CSRF token missing.): /courses/2/learning-django

это мои модели

class Review(models.Model):
    course = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='reviews')
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    rating = models.IntegerField(null=True, validators=[MinValueValidator(1), MaxValueValidator(5)])
    comment = models.TextField()
    created = models.DateField(auto_now_add=True)
    active = models.BooleanField(default=False)
    
    def __str__(self):
        return f'{self.first_name} {self.last_name}

мои взгляды:

def productDetailView(request, id, slug):
    product = get_object_or_404(Product, id=id, slug=slug, available=True)
    new_comment = None
    
    if request.method == 'POST':
        form = ReviewForm(request.POST)
        if form.is_valid():
            new_comment = form.save(commit=False)
            new_comment.course = product
            new_comment.rating = request.POST['rating']
            new_comment.save()
    else:
        form = ReviewForm()
    
    return render(request, 'shop/product_detail.html', {'product': product, 'form': form})

js функция:

$(document).ready(function(){
        $('.rate .rate-item').on('click', function(){
            var value = $(this).data('value');
            $.ajax({
                url: '{{ product.get_absolute_url }}',
                type: 'POST',
                data: {'rating': value},
                success: function(response){
                    alert('Rating saved successfully!');
                }
            });
        });
    });

мой шаблон

<form method="post">                                            
<div class="row">
<div class="col-md-6">
<div class="form-singel">
{{ form.first_name|attr:" placeholder:Fast name" }}
</div>
</div>
<div class="col-md-6">
<div class="form-singel">
{{ form.first_name|attr:" placeholder:Last Name"}}
</div>
</div>
<div class="col-lg-12">
<div class="form-singel">
<div class="rate-wrapper">
<div class="rate-label">Your Rating:</div>
<div class="rate">
<div data-value="1" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
<div data-value="2" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
<div data-value="3" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
<div data-value="4" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
<div data-value="5" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
</div>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="form-singel">
{{ form.first_name|attr:" placeholder:Comment" }}                                                                                               
</div>
</div>
{% csrf_token %} 
<div class="col-lg-12">
<div class="form-singel">
<button type="submit" class="main-btn">Post Comment</button>
</div>
</div>
</div> <!-- row -->                                 
</form>

Я использовал csrf_token в своей форме, но похоже, что это не работает и я искал в stackoverflow ни у кого нет такой же ошибки

как мне это исправить

Если вы хотите сделать AJAX запрос, вам необходимо добавить CSRF токен в тело данных.

$.ajax({
    url: '{{ product.get_absolute_url }}',
    type: 'POST',
    data: {'rating': value, csrfmiddlewaretoken: '{{ csrf_token }}'},
    success: function(response){
        alert('Rating saved successfully!');
    }
});

Оригинальный ответ: https://stackoverflow.com/a/6170377/5711733

По сути, вам не хватает csrftoken в форме data.

У вас есть две возможности:

Либо определите вид с помощью @csrf_exempt:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def productDetailView(request, id, slug):
    product = get_object_or_404(Product, id=id, slug=slug, available=True)
    new_comment = None

Или загрузить переменную из cookie и передать ее в заголовки (я использую библиотеку js-cookie, но вы можете найти отдельные функции на stack overflow, которые подойдут для ваших нужд) - пример:

$.ajax({
    url: url,
    type: 'POST',
    headers: {
        'X-CSRFTOKEN': Cookies.get('csrftoken'),
    },
    success: (data) => {
        location.reload();
    }
})

Из того, что я знаю, первое решение должно быть более безопасным.

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