我想在Django中创建一个5星评分系统,但它一直出现这个错误:

huangapple go评论54阅读模式
英文:

I wanted to craete a 5 star rating system in django but it keeps getting this error:

问题

我查阅了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})

JavaScript函数:

$(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 %},但似乎不起作用,我在Stack Overflow 上搜索没有找到相同的错误。

你可以尝试以下方法来解决CSRF令牌缺失的问题:

  1. 确保你的Django应用已经包含了'django.middleware.csrf.CsrfViewMiddleware'中间件。在MIDDLEWARE设置中确认。

  2. 确保你的HTML模板中的表单包含{% csrf_token %}标签,它应该在<form>标签内部,例如:

    <form method="post">
    {% csrf_token %}
    <!-- 其他表单字段 -->
    </form>
    
  3. 在JavaScript中,确保你的AJAX请求的URL是正确的,它应该指向你的Django视图,并且这个视图应该在csrf_exempt中设置为False,以便Django能够验证CSRF令牌。

  4. 如果你仍然遇到问题,尝试清除浏览器缓存或使用不同的浏览器来测试,有时浏览器缓存可能导致CSRF问题。

希望这些方法有助于解决你的CSRF令牌问题。如果问题仍然存在,请提供更多细节,以便我能够提供更具体的帮助。

英文:

i check with django document and But my problem was not solved
[08/Feb/2023 15:57:18] "POST /courses/2/learning-django HTTP/1.1" 403 2506
error:
Forbidden (CSRF token missing.): /courses/2/learning-django

this is my models

class Review(models.Model):
course = models.ForeignKey(Product, on_delete=models.CASCADE, related_name=&#39;reviews&#39;)
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&#39;{self.first_name} {self.last_name}

my views:

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

js function:

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

my template

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

I used csrf_token in my form but it seems that dosen't work
and i searched in stackoverflow no one have same error

how do i fix it

答案1

得分: 0

如果你想要进行AJAX请求,你需要将CSRF令牌添加到数据主体中。

$.ajax({
    url: '{{ product.get_absolute_url }}',
    type: 'POST',
    data: {'rating': value, csrfmiddlewaretoken: '{{ csrf_token }}'},
    success: function(response){
        alert('评分保存成功!');
    }
});

原始答案:https://stackoverflow.com/a/6170377/5711733

英文:

If you want to make AJAX request, you need to add CSRF token to the data body.

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

Original answer: https://stackoverflow.com/a/6170377/5711733

答案2

得分: 0

你错过的基本上是表单数据中的 csrftoken

你有两种可能性:

要么定义视图并使用 @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();
    }
})

据我所知,第一种解决方案应该更安全。

英文:

Basically what you miss is csrftoken in the form data.

You have two possibilities:

Either define view with @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

Or load variable from cookie and pass it into headers (I'm using js-cookie library but you can find single functions on stack overflow that will fit your needs) - example:

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

From what I know first solution should be more secure.

huangapple
  • 本文由 发表于 2023年2月9日 00:33:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75388876.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定