我无法从 JQuery ajax 调用中加载部分 Django 模板

Posted

技术标签:

【中文标题】我无法从 JQuery ajax 调用中加载部分 Django 模板【英文标题】:I can't load a Django template partial from a JQuery ajax call 【发布时间】:2021-11-09 00:56:07 【问题描述】:

我需要使用 JQuery 从 ajax 调用发送一个列表,并在其中发送一个带有 Django variables 的响应,我尝试了一切,但 JQuery 总是加载整个当前页面而不是加载 html 文件包含模板部分,它只是

<!-- city_dropdown_list_options.html -->
<option value="">----city list----</option>
% for city in cities %
    <option value=" city.pk "> city.name </option>
% endfor %

这里是JQuery所在的模板

person_form.html

% extends 'base.html' %
% load i18n %
% load static %
# NOTE: templates must be defined into a folder having the same name than 
the application, like here countries/person_list.html, because Django 
automatically search from <template_folder_in_app_folder/app_name/template.html #
% block content %
    <h2>% trans "Person Form" %</h2>
    <form method="post" novalidate>
        % csrf_token %
        <table>
             form.as_table 
        </table>
        <button type="submit">Save</button>
        <a href="% url 'person_changelist' %">Nevermind</a>
    </form>
    <div id="test"></div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
# <script src="% static 'js/test.js' %"></script> #
<script>
    $("#id_country").change(function ()
        // getting the url of the load_cities view
        var url = $("#personForm").attr("data-cities-url");
        
        // get the selected country id from the html element
        var countryId = $(this).val(); 
        $.ajax(
            url: url,
            data: 
                // adding the countryId to GET parameters
                'country': countryId
            ,
            // data is the return value of the 'load_cities' function
            success: function(data)
                // replace the contents of the city input with the data 
                // that came from the server. 
                //console.log(data);
                $("#id_city").html(data); 
                // $('#id_city').html(jQuery(data).find('#id_city').html());  
                        
        );
    );
</script>
% endblock %

views.py

from django.shortcuts import render
from django.views.generic import ListView, CreateView, UpdateView
from django.urls import reverse_lazy
from .models import Person, City
from .forms import PersonForm


class PersonListView(ListView):
    model = Person
    context_object_name = 'people'


class PersonCreateView(CreateView):
    model = Person
    form_class = PersonForm
    success_url = reverse_lazy('person_changelist')


class PersonUpdateView(UpdateView):
    model = Person
    form_class = PersonForm
    success_url = reverse_lazy('person_changelist')


def load_cities(request):
    country_id = request.GET.get('country')
    cities = City.objects.filter(country_id=country_id).order_by('name')
    return render(request, 'countries/city_dropdown_list_options.html', 'cities': cities)

项目级别的 urls.py

from django.urls import path, include
from django.views.generic import RedirectView
from django.conf.urls.i18n import i18n_patterns
import debug_toolbar
from django.conf import settings

urlpatterns = i18n_patterns(
    path('', RedirectView.as_view(pattern_name='person_changelist'), name='home'),
    path('countries/', include('countries.urls')),
    path('__debug__/', include(debug_toolbar.urls)),
    prefix_default_language=False
)

应用级别的 urls.py:

from django.urls import include, path
from . import views

urlpatterns = [
    path('', views.PersonListView.as_view(), name='person_changelist'),
    path('add/', views.PersonCreateView.as_view(), name='person_add'),
    path('<int:pk>/', views.PersonUpdateView.as_view(), name='person_change'),
    path('load-cities/', views.load_cities, name='ajax_load_cities'),
    path('man/load-cities/<int:pk>/', views.load_cities2, name='man_load_cities'),
]

正如我所说,我收到整个 person_form.html 作为响应,而我希望 city_dropdown_list_options.html 作为响应。请注意,响应不一定是包含的 html 部分,也可以是视图生成的简单输出。

我在 JQuery 方面不是很好,可能我做错了或遗漏了一些事情。有什么线索吗?

【问题讨论】:

您是否将 async 属性添加到您的 ajax 调用中? 我应该添加它吗?我认为它已经默认设置了。无论如何,我已经通过在下拉列表更改并且可以正常工作时在测试 div 中发送“Hello Word”来测试异步行为。我怀疑问题可能是由于 $("#id_city").html(data);或者可能在收到的响应的内容中。 【参考方案1】:

我找到了解决办法

一行

path('load-cities/', views.load_cities, name='ajax_load_cities'),

在 urls.py(应用程序级别)中丢失。这意味着路由没有被定义为由 JQuery ajax 调用调用。因此调用是

http://127.0.0.1:8000/countries/add/?country=56

与表单的 url 相同,但管理不当。

我发现这种问题的最佳解决方案是像我一样为 ajax 调用创建一个专用路由,这样 cal 就变成了

http://127.0.0.1:8000/countries/add/load-cities/?country=56

这样的做法也毫无意义

var url = $("#personForm").attr("data-cities-url");

我换成了直接明了的:

var url = "/countries/load-cities/";

现在一切都很好。

故事的寓意: 当您使用 JQuery 并在 Django 模板中进行 ajax 调用时,永远不要忘记在 urls.py 中定义专用路由。请记住,您正在使用具有内置路由系统的框架。 php_SELF 等效项在这里不再起作用。

辛苦了3天,终于搞定了。我希望这个对我自己问题的回答能帮助其他面临同样问题的人。

【讨论】:

以上是关于我无法从 JQuery ajax 调用中加载部分 Django 模板的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 没有在 ajax 请求的脚本标签中加载 js 文件

无法从您的配置中加载“paypal”部分

在 WebMatrix 中加载 jQuery VSDoc

在 django 应用程序中加载的 Ajax 调用时间

如何在 Wordpress 中加载 Ajax

如何正确渲染部分视图,并使用 Express/Jade 在 AJAX 中加载 JavaScript 文件?