【问题标题】:Django: Passing a csrf token through ajax to an UpdateView 405 method not found errorDjango:通过ajax将csrf令牌传递给UpdateView 405方法未找到错误
【发布时间】:2017-02-24 09:30:29
【问题描述】:

我正在创建一个常见问题解答应用程序。在我的文章详细信息页面中,我正在尝试实施投票系统。目标是允许用户在发现文章有用时对其进行投票。我不希望在用户单击投票按钮时刷新页面。我选择使用从模板到更新视图的 url 的 Ajax 调用。

Django 需要一个 csrf 令牌来传递。我遇到的问题是405 (Method Not Allowed) 错误。我已经在 chrome dev 的网络设置中验证了 csrf 令牌正在生成并在 http 标头中分配。我认为问题可能存在于视图中,但到目前为止我所做的一切都失败了。任何方向都会有所帮助。

编辑更新:

我正在使用 Django 1.10

网址:

from django.conf.urls import url
from faq.views import *

urlpatterns = [
    url(r'^ironfaq/$', DashboardView.as_view()),
    url(r'^ironfaq/(?P<slug>[\w-]+)/$', SectionView.as_view()),
    url(r'^ironfaq/(?P<topic_slug>[\w-]+)/(?P<section_slug>[\w-]+)/(?P<pk>\d+)/$',
        ArticleDetailView.as_view(), name="faq-article-detail"),
    url(r'^ironfaq/topic/create/$', TopicCreateView.as_view()),
    url(r'^ironfaq/section/create/$', SectionCreateView.as_view()),
    url(r'^ironfaq/(?P<topic_pk>\d+)/article/create/$', ArticleCreateView.as_view()),
    url(r'^ironfaq/topic/update/(?P<pk>\d+)/$', TopicUpdateView.as_view()),
    url(r'^ironfaq/section/update/(?P<pk>\d+)/$', SectionUpdateView.as_view()),
    url(r'^ironfaq/article/update/(?P<pk>\d+)/$', ArticleUpdateView.as_view()),
    url(r'^ironfaq/topic/delete/(?P<pk>\d+)/$', TopicDeleteView.as_view()),
    url(r'^ironfaq/section/delete/(?P<pk>\d+)/$', SectionDeleteView.as_view()),
    url(r'^ironfaq/article/delete/(?P<pk>\d+)/$', ArticleDeleteView.as_view()),
    url(r'^ironfaq/article/vote/(?P<pk>\d+)$/', ArticleVoteView.as_view()),
]

模板脚本:

{% block scripts %}
<script>
$(document).ready(function(){
    var csrftoken = Cookies.get('csrftoken');

    function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    $.ajaxSetup({
        beforeSend: function(xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrftoken);
            }
        }
    });


    function post_call(vote_data){
        var data = {vote_type: vote_data};
        var id = {{ object.id }};
        $.ajax({
            url: "/ironfaq/article/vote/"+id+"/",
            type: "POST",
            data: data,
        }).done(function() {
           console.log("POST!"); 
        });
    }

    var vote_up = "vote_up";
    var vote_down = "vote_down";

    var thumbs_up = $('#thumbs_up');
    var thumbs_down = $('#thumbs_down');

    thumbs_up.on('click', function(){
        post_call(vote_up)
    });
    thumbs_down.on('click', function(){
        post_call(vote_down)
    });
});
</script>
{% endblock %}

观点:

class ArticleVoteView(UpdateView):
    model = Article
    fields = []

    def form_valid(self, form):
        article = form.save(commit=False)
        vote_type = self.request.POST.get('vote_type')

        if vote_type == 'vote_up':
            article.vote_up = article.vote_up + 1
            article.save()
        elif vote_down == 'vote_down':
            article.vote_down = article.vote_down + 1
            article.save()

        data = {'status': 'success', 'vote_type': vote_type, 'yes_count': article.vote_up, 
                'total_votes': article.total_votes()}

        return HttpResponse(json.dumps(data))

【问题讨论】:

  • Django 不喜欢没有斜杠的 url - 从那里开始,因为它可能会做一些重定向。如果这没有帮助,您可以随时尝试重载视图 dispatch 方法以查看正在构建什么样的请求 - 在该方法中使用 pdb
  • 您确定该视图正在处理该网址吗?请显示您的网址格式。
  • 已进行编辑以显示所有网址。

标签: jquery ajax django csrf django-csrf


【解决方案1】:

您对/ironfaq/article/vote/&lt;id&gt; 的发帖请求似乎与此网址模式匹配:

url(r'^ironfaq/(?P<topic_slug>[\w-]+)/(?P<section_slug>[\w-]+)/(?P<pk>\d+)/$',
    ArticleDetailView.as_view(), name="faq-article-detail"),

由于详细视图仅处理获取请求,因此您的发布请求会导致 405 响应。

您需要重新设计您的网址格式以使其不会发生冲突,或者将faq-article-detail 网址格式移动到投票网址格式(以及与之发生冲突的任何其他格式)下方。

【讨论】:

    猜你喜欢
    • 2023-04-02
    • 2017-04-12
    • 2016-06-22
    • 2014-10-12
    • 2018-10-23
    • 2018-02-18
    • 2021-01-04
    • 2015-11-22
    • 2015-01-31
    相关资源
    最近更新 更多