javascript - 如何通过 AJAX post 请求将两个依赖下拉列表的值发送到 Django View ?

标签 javascript django ajax

我目前正在尝试将两个下拉列表的值发送到 django View 。如果下拉菜单是独立的,我的代码就会正常工作。问题是事实并非如此。第一个更新第二个,因此我需要在第二个下拉列表更新后发出 AJAX post 请求。

这是我当前的 html/Javascript 代码:

<select name="d1" class="toChange">
    {% for item in items1 %}
    <option val="{{ item }}"> {{ item }} </option>    
    {% endfor %}
</select>

<select name="d2">
    {% for item in items2 %}
    <option val="{{ item }}"> {{ item }} </option>    
    {% endfor %}
  </select>


<script type="text/javascript">
  function dropdownChange () {
    var value_d1 = $(".toChange option:selected").val();
    var value_d2 = $("select[name=d2] option:selected").val();
    $.ajax({
            url: '/myApp/templates/',
            type: 'POST',
            data: {'d1': value_d1, 'd2': value_d2},
            success: function(data) {
              var str = '';
              data.forEach(function(opt){
              str += '<option value="' + opt + '">' + opt + '</option>';
              });
              document.getElementById("d2").innerHTML = str;
            }
    });
    $(".toChange").change(dropdownChange);

所以这里 d1 中的更改更新了 d2,但 AJAX 调用是在 d2 更新之前进行的,因此将错误的值发送到我的 View 。我该如何克服这个问题?

更新:添加TM.96建议的代码

 <select id="d1" name="d1" class="toChange">
    {% for item in items1 %}
    <option val="{{ item }}"> {{ item }} </option>    
    {% endfor %}
  </select>

  <select id="d2" name="d2">
    {% for item in items2 %}
    <option val="{{ item }}"> {{ item }} </option>    
    {% endfor %}
  </select>


<script type="text/javascript">

let select1 = document.getElementById('d1');
let select2 = document.getElementById('d2');

function onChangeSelect1() {

    window.select2.value = window.select1.options[window.select1.selectedIndex].value;

    onChangeSelect2();
}

function onChangeSelect2() {
    console.log('Value of Select 1: ' + window.select1.value);
    console.log('Value of Select 2: ' + window.select2.value);

    $.ajax({
            url: '/myApp/templates/',
            type: 'POST',
            data: {'d1': select1, 'd2': select2},
            success: function(data) {
              var str = '';
              data.forEach(function(opt){
              str += '<option value="' + opt + '">' + opt + '</option>';
              });
              document.getElementById("d2").innerHTML = str;
            }
    }); 
}
$(".toChange").change(dropdownChange);

</script>

更新2:

def MyView(request):

    if request.method == 'POST' and request.is_ajax:


        result_r = request.POST.get('d1')
        result_d = request.POST.get('d2')
        query_results = data_immo.objects.all()
        regions = data_immo.objects.values_list("nom_reg", flat=True).distinct().order_by('nom_reg')
        departments = data_immo.objects.values_list("insee_dep").filter(Q(nom_reg=result_r)).distinct()
        cities = data_immo.objects.values_list("nom_com").filter(Q(insee_dep=result_d)).distinct()

        print(departments)

        query_results_dict = {
        'query_results': query_results,
        'regions': regions,
        'departments': departments,
        'reg': result_r
        }

        departmentsVar=[]
        for item in departments:
            item = int(item[0])
            departmentsVar.append(item)

        departmentsVar.sort()
        departmentsVar = json.dumps(departmentsVar)

        citiesVar=[]
        for item in cities:
            citiesVar.append(item)

        citiesVar.sort()
        citiesVar = json.dumps(citiesVar)


        return HttpResponse(departmentsVar, content_type='application/json')

从技术上讲,我需要返回partmentsVar和cityVar,但由于某些原因我的尝试失败了。看来我只能返回一个变量(所以这里是departmentsVar)。我尝试将两者添加到字典中,但没有成功。

最佳答案

好的,我在下面为您提供了一个最小的工作示例:

服务器端:

urls.py

urlpatterns = [
    path('Ajax/Test', views.ajax_test),
]

views.py

def ajax_test(request):
    return JsonResponse(request.GET)

客户端:

HTML

<label for="selectCity">City:</label>
<select id="selectCity" onchange="onChangeSelectCity()">
    <option disabled selected value> -- select an option --</option>
    <option value="1">Munich</option>
    <option value="2">Los Angeles</option>
</select>

<label for="selectState">State:</label>
<select id="selectState" onchange="onChangeSelectState()">
    <option disabled selected value> -- select an option --</option>
    <option value="1">Bavaria</option>
    <option value="2">California</option>
</select>

<label for="selectCountry">Country:</label>
<select id="selectCountry" onchange="onChangeSelectCountry()">
    <option disabled selected value> -- select an option --</option>
   <option value="1">Germany</option>
   <option value="2">United States</option>
</select>

Javascript

<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.4.1.min.js"
    integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" 
    crossorigin="anonymous"></script>

<!-- JavaScript example code -->
<script>
// Set global variables. You can also set these inside the functions and use 
// them as local variables.
// When you declare a variable outside the function, it is added in the 
// window object internally.
let selectCity = document.getElementById('selectCity');
let selectState = document.getElementById('selectState');
let selectCountry = document.getElementById('selectCountry');

// Triggers if Select City changes.
function onChangeSelectCity() {
    // Print values of the select fields in console.
    console.log('On change Select City:');
    console.log('Value of Select City: ' + window.selectCity.value);
    console.log('Value of Select State: ' + window.selectState.value);
    console.log('Value of Select Country: ' + window.selectCountry.value);

    // Call function that is also called if Select State changes.
    onChangeSelectState(window.selectCity.value);
}

// Triggers if Select State changes.
function onChangeSelectState(value = 0) {
    // If function got called from onChangeSelectCity.
    if (value > 0) {
        window.selectState.value = value;
    }

    // Print values of the select fields in console.
    console.log('On change Select State:');
    console.log('Value of Select City: ' + window.selectCity.value);
    console.log('Value of Select State: ' + window.selectState.value);
    console.log('Value of Select Country: ' + window.selectCountry.value);

    // Call function that is also called if Select Country changes.
    onChangeSelectCountry(window.selectState.value);
}

// Triggers if Select Country changes.
function onChangeSelectCountry(value = 0) {
    // If function got called from onChangeSelectState.
    if (value > 0) {
        window.selectCountry.value = value;
    }

    // Print values of the select fields in console.
    console.log('On change Select Country:');
    console.log('Value of Select City: ' + window.selectCity.value);
    console.log('Value of Select State: ' + window.selectState.value);
    console.log('Value of Select Country: ' + window.selectCountry.value);

    // Put your ajax code here...
    let url = 'Ajax/Test';

    $.ajax({
        type: "GET",
        data: {
            'city': window.selectCity.value,
            'state': window.selectState.value,
            'country': window.selectCountry.value
        },
        url: url,
        success: function (data) {
            console.log(data);
        }
    });
}
</script>

说明:

我设置了三个选择字段(城市、州和国家/地区)。

  1. 如果城市发生变化,州和国家/地区将根据城市进行更新。
  2. 如果“州”发生更改,“国家/地区”将根据“州”进行更新。城市不会改变。
  3. 如果国家/地区发生更改,则不会更新任何内容。城市和州不会改变。

在所有三种情况下都会触发 ajax 调用,并将正确的值(无或已设置)发送到 django View 。此外,django View 会返回值,并且它们将在控制台中正确打印。

关于javascript - 如何通过 AJAX post 请求将两个依赖下拉列表的值发送到 Django View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60623354/

相关文章:

javascript - jsTree自定义上下文菜单不根据类型文件夹/文件进行过滤

mysql - OneToOneField 获取 "Cannot resolve keyword"

Graphite 烯模式中的Django http-request

sql - Django与select_related的反向关系

javascript - 如何在 JavaScript 中找到 .data() (jQuery) 等效项?

javascript - ExtJS - 更新 DIV 后无法再次渲染窗口

jquery - Ajax提交表单安全吗?

javascript - 跨浏览器窗口大小调整事件 - JavaScript/jQuery

javascript - 使用 Javascript 在 HTML 中双击空白时选择上一个和下一个单词

javascript - 增加以两种不同方式动态创建的单选按钮