【问题标题】:Ajax call to view giving me a 404 error but it's the right URL in DjangoAjax 调用查看给我一个 404 错误,但它是 Django 中的正确 URL
【发布时间】:2020-05-17 22:06:39
【问题描述】:

我正在尝试通过 Ajax 和 Django 发送一个 post 请求,但即使 POST url 是我想要使用的正确 URL,我仍然收到 404 错误。

这是我的最小化表单,我试图通过一个按钮发送和赋值。

<form class='my-ajax-form' method='POST'>{% csrf_token %}

  <div class="btn-group" role="group" aria-label="Basic example">
  <button type="text" class="btn btn-danger hard" name="hard" value="HARD">HARD </button>
  </div>

</form>

这是我的 Ajax 表单:

我的 CSRF 代码之前出现错误,但现在没有。

<script>
             $(document).ready(function() {

                function getCookie(name) {
                var cookieValue = null;
                if (document.cookie && document.cookie != '') {
                    var cookies = document.cookie.split(';');
                    for (var i = 0; i < cookies.length; i++) {
                        var cookie = jQuery.trim(cookies[i]);
                        // Does this cookie string begin with the name we want?
                        if (cookie.substring(0, name.length + 1) == (name + '=')) {
                            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                            break;
                        }
                    }
                }
                return cookieValue;

            }
            var csrftoken = getCookie('csrftoken');
            var $endpoint = $(location).attr('href')

            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);
                    }
                }
            });

我的 Ajax 调用:

            $('.hard').click(function(e) {
                event.preventDefault();
                var $hard = $(".hard").text();
                console.log($hard) 

                $.ajax({                        
                    method:'POST',
                    url: $endpoint,
                    data: $hard,
                })                   

            })   
            });

我的网址文件

urlpatterns =[

path('profile/<int:pk>/',  login_required(UserUpdateView.as_view()), name='profile'),

]

我的结果是 → POST http://127.0.0.1:8000/profile/11/ 404 (Not Found)

创建调用的url是http://127.0.0.1:8000/profile/11/

我只是想将请求发送到视图,仅在控制台中的屏幕上没有错误。

感谢您的帮助

已请求查看,但 POST 请求未到达该视图。这里是

class UserUpdateView(UpdateView):

model = user_content
template_name = 'users/profile.html'
model_words = single_words_cards



def get(self, request, *args, **kwargs):
    model = user_content
    model_words = single_words_cards
    template_name = 'users/profile.html'
    user_id_fk = request.user.id



    # Hide the sentance
    if request.method == "POST":

        if request.GET.get('hard') == 'hard':
            print('hard was found')
        else:
            print('nothing')

        hide = model.objects.filter(show_sentance = True).values('sentance_eng').filter(id=query)
        model.objects.filter(id=retire).update(show_sentance='False')
        print(retire )


    #Querysets 
    user_sentances = model.objects.filter(show_sentance = True).values('sentance_eng', 'sentance_esp', 'id', 'username_id', 'show_sentance').filter(username_id = user_id_fk) 
    zip_flash_sentances = model.objects.filter(show_sentance=True).order_by("?").filter(username_id = user_id_fk).values_list('sentance_eng', 'sentance_esp', 'id').first()
    number_sentances_today = model.objects.filter(show_sentance=True).values_list('sentance_eng').filter(username_id = user_id_fk).count()

    word_cards_esp = list(model_words.objects.filter(show_word=True).values_list('word_esp').filter(username_id = user_id_fk))
    word_cards_eng = list(model_words.objects.filter(show_word=True).values_list('word_eng').filter(username_id = user_id_fk))
    number_of_cards = len(model_words.objects.filter(show_word=True).values_list('word_esp').filter(username_id = user_id_fk))

    value = random.randint(0,number_of_cards)-1


    words_esp = word_cards_esp[value] 
    words_eng = word_cards_eng[value]




    return render(request, template_name, {'sentances_list': user_sentances,
                                           'zip_flash_sentances':zip_flash_sentances,
                                           'words_esp':words_esp,
                                           'words_eng':words_eng,
                                           'number_sentances_today':number_sentances_today, 
                                           'number_of_cards':number_of_cards, 
                                           'user_id_fk': user_id_fk,

                                           })

【问题讨论】:

  • 请显示视图。 UserUpdateView 是什么?
  • 我问的原因是它是第一个项目,因为现在许多教程制作者没有解释为什么你应该这样做这样。看完本教程后,您既不知道替代方法也不知道高级方法。我的建议是找到好的社区(可能是你当地的 pyCon)。
  • 也许您遇到此问题是因为 url 相互冲突,请在控制台中添加您的其他 url 和错误。还有一个疑问,你能向127.0.0.1:8000/profile/11 url 发出GET 请求吗?
  • 你能在 Django shell 中试试这个吗(我在 1.11 版),看看这不会抛出 403:from django.urls import resolve; resolver_match = resolve('/profile/1/')

标签: django ajax


【解决方案1】:

UpdateView中的post请求,需要创建post方法。

这样的事情会起作用:

class UserUpdateView(UpdateView):

    model = user_content
    template_name = 'users/profile.html'
    model_words = single_words_cards


    # Get Method 
    def get(self, request, *args, **kwargs):
        model = user_content
        model_words = single_words_cards
        template_name = 'users/profile.html'
        user_id_fk = request.user.id

        #Querysets 
        user_sentances = model.objects.filter(show_sentance = True).values('sentance_eng', 'sentance_esp', 'id', 'username_id', 'show_sentance').filter(username_id = user_id_fk) 
        zip_flash_sentances = model.objects.filter(show_sentance=True).order_by("?").filter(username_id = user_id_fk).values_list('sentance_eng', 'sentance_esp', 'id').first()
        number_sentances_today = model.objects.filter(show_sentance=True).values_list('sentance_eng').filter(username_id = user_id_fk).count()

        word_cards_esp = list(model_words.objects.filter(show_word=True).values_list('word_esp').filter(username_id = user_id_fk))
        word_cards_eng = list(model_words.objects.filter(show_word=True).values_list('word_eng').filter(username_id = user_id_fk))
        number_of_cards = len(model_words.objects.filter(show_word=True).values_list('word_esp').filter(username_id = user_id_fk))

        value = random.randint(0,number_of_cards)-1


        words_esp = word_cards_esp[value] 
        words_eng = word_cards_eng[value]




        return render(request, template_name, {'sentances_list': user_sentances,
                                            'zip_flash_sentances':zip_flash_sentances,
                                            'words_esp':words_esp,
                                            'words_eng':words_eng,
                                            'number_sentances_today':number_sentances_today, 
                                            'number_of_cards':number_of_cards, 
                                            'user_id_fk': user_id_fk,

                                            })

    # Post Method 
    def post(self, request, *args, **kwargs):
        model = user_content
        model_words = single_words_cards
        template_name = 'users/profile.html'
        user_id_fk = request.user.id


        if request.GET.get('hard') == 'hard':
            print('hard was found')
        else:
            print('nothing')

        hide = model.objects.filter(show_sentance = True).values('sentance_eng').filter(id=query)
            model.objects.filter(id=retire).update(show_sentance='False')
        print(retire )
        # Process your request

【讨论】:

  • 404 因为它找不到post 方法。这是正确的答案。
【解决方案2】:

问题出在视图中。在基于类的视图中,您需要单独定义每个方法。在您的代码中只有 GET 方法。 POST 方法需要另一个函数。

【讨论】:

  • 那么状态码应该是405 [Method not allowed],而不是404。
【解决方案3】:

我假设您的 urls.py 不在 Django 项目目录中,而是在您的应用程序目录之一中,因此在 url_patterns 之前包含 app_name。可以分享一下你的目录结构吗?

【讨论】:

    【解决方案4】:

    问题在于您的网址格式

    urls.py

    from django.conf.urls import url
    
    urlpatterns = [
        url(r'^profile/(?P<your_variable_name>\d+)/$', login_required(UserUpdateView.as_view()), name='profile'),
        ]
    

    注意:您的视图中可能会出现参数错误,因此您可以使用

    def your_view(request, your_argument):
    

    【讨论】:

    • 您所做的只是将 2.x 网址表示法更改为 1.x。在功能上,你的答案是相同的
    • 与什么相同?
    • 与 OP 发布的 url 配置相同
    • 路径和url有区别。你在说什么?除了这个答案是有效的,而有问题的代码不是
    • pathurl 之间存在细微差别,但在功能上不会影响 OP 的情况。您的解决方案非常适合 1.11.x,但 OP 在 2.x 中很好
    猜你喜欢
    • 2016-10-10
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-19
    • 2018-03-20
    • 2018-12-23
    相关资源
    最近更新 更多