为什么我的级联下拉表单的选项没有出现?

问题描述 投票:0回答:1

我正在构建一个汽车维修估算器,需要创建一个依赖下拉列表,允许用户根据他们选择的品牌从各种模型中进行选择。我可以看到并选择不同的品牌,但看不到不同的型号。我正在使用 Django 框架并将品牌和型号存储在 Postgresql 数据库中

这是我的应用程序现在正在发生的事情:Ford models are supposed to be here

这是我的应用程序 AutoBuddy 的工作主管的快照: Working Directory

这是我的 ABDjango/templates/models/home.html 文件中的代码:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Dependent Dropdown in Django</title>
</head>
<body>
<h2>Car Form</h2>

<form method="post" id="modelForm" data-models-url="{% url 'ajax_load_models' %}">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Submit">
</form>

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
    $("#id_model").change(function () {
        const url = $("#modelForm").attr("data-models-url");  // get the url of the `load_cities` view
        const modelId = $(this).val();  // get the selected country ID from the HTML input
        $.ajax({    
                               // initialize an AJAX request
            url: url,                    // set the url of the request (= /persons/ajax/load-cities/ )
            data: {
                'model_id': modelId       // add the country id to the GET parameters
            },
            success: function (data) {   // `data` is the return of the `load_cities` view function
                $("#id_model").html(data);  // replace the contents of the city input with the data that came from the server
                /*
                let html_data = '<option value="">---------</option>';
                data.forEach(function (city) {
                    html_data += `<option value="${city.id}">${city.name}</option>`
                });
                console.log(html_data);
                $("#id_city").html(html_data);
                */
            }
        });

    });
</script>

</body>
</html>

这是我的 ABDjango/templates/models/model_dropdown_list_options.html 文件中的代码:

<option value="">---------</option>
{% for model in models %}
<option value="{{ model.pk }}">{{ model.name }}</option>
{% endfor %}

这是我的 ABDjango/urls.py 文件中的代码:

from django.contrib import admin
from django.urls import path
from django.conf.urls import include

urlpatterns = [
    path('users/', include('autobuddyapp.urls')),
    path('admin/', admin.site.urls)

这是我的 autobuddy/models.py 文件中的代码:

from django.db import models


   class Make (models.Model):
      name = models.CharField(max_length=40)

      def __str__(self):
         return self.name


   class Model(models.Model):
      make = models.ForeignKey(Make, on_delete=models.CASCADE)
      name = models.CharField(max_length=40)

      def __str__(self):
         return self.name


   class Car(models.Model):
      year = models.CharField(max_length=124)
      make = models.ForeignKey(Make, on_delete=models.SET_NULL, blank=True, null=True)
      model = models.ForeignKey(Model, on_delete=models.SET_NULL, blank=True, null=True)

      def __str__(self):
         return self.year + " " + str(self.make) + " " + str(self.model)

这是我的 autobuddy/urls.py 文件中的代码:

from django.urls import path
from . import views

urlpatterns = [
    path('add/', views.model_create_view, name='model_add'),
    path('<int:pk>/', views.model_update_view, name='model_change'),
    path('ajax/load-models/', views.load_models, name='ajax_load_models'), # AJAX
]

这里是 autobuddy/views.py:

from django.http import JsonResponse
from django.shortcuts import render, redirect, get_object_or_404

from .forms import ModelCreationForm
from .models import Make, Model, Car


def model_create_view(request):
    form = ModelCreationForm()
    if request.method == 'POST':
        form = ModelCreationForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('model_add')
    return render(request, 'models/home.html', {'form': form})


def model_update_view(request, pk):
    car = get_object_or_404(Car, pk=pk)
    form = ModelCreationForm(instance=car)
    if request.method == 'POST':
        form = ModelCreationForm(request.POST, instance=car)
        if form.is_valid():
            form.save()
            return redirect('model_change', pk=pk)
    return render(request, 'models/home.html', {'form': form})


# AJAX
def load_models(request):
    model_id = request.GET.get('model_id')
    models = Model.objects.filter(model_id = model_id).all()
    return render(request, 'models/model_dropdown_list_options.html', {'models': models})
    # return JsonResponse(list(cities.values('id', 'name')), safe=False)

Autobuddy/forms.py

from django import forms

from autobuddyapp.models import Make, Model, Car

class ModelCreationForm(forms.ModelForm):
    class Meta:
        model = Car
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['model'].queryset = Model.objects.none()

        if 'make' in self.data:
            try:
                make_id = int(self.data.get('make'))
                self.fields['model'].queryset = Model.objects.filter(make_id=make_id).order_by('name')
            except (ValueError, TypeError):
                pass  # invalid input from the client; ignore and fallback to empty City queryset
        elif self.instance.pk:
            self.fields['model'].queryset = self.instance.model.make_set.order_by('name')
python django cascadingdropdown
1个回答
0
投票

第一个问题就在脚本的第一行:

<script>
    $("#id_model").change(function () {
        ...

您正试图在错误的选择上捕获更改事件,它应该在

id_make
上。响应方法和您尝试更新选择器的方式也存在问题。

Response 应该是一个 JSON 对象。要更新选择器,我们需要创建

options
并添加到特定元素,在本例中为
id_model
。 (此外,我们需要在再次填充之前清除它)

views.py

def load_models(request):
    make_id = request.GET.get('make_id')
    models = list(Model.objects.filter(make__id = make_id).values())
    return JsonResponse({'models': models})

template.html

<script>
    $("#id_make").change(function () {
        const url = $("#modelForm").attr("data-models-url");  // get the url of the `load_cities` view
        const makeId = $(this).val();  // get the selected country ID from the HTML input
        $.ajax({
                               // initialize an AJAX request
            url: url,                    // set the url of the request (= /persons/ajax/load-cities/ )
            data: {
                'make_id': makeId       // add the country id to the GET parameters
            },
            success: function (data) {   // `data` is the return of the `load_cities` view function
                $('#id_model').empty();
                for (let i = 0; i < data.models.length; i++) {
                    var option = $('<option/>');
                    option.attr({ 'value': data.models[i].id }).text(data.models[i].name);
                    $('#id_model').append(option);
                }
            }
        });

    });
</script>

其他一切,保持不变。

© www.soinside.com 2019 - 2024. All rights reserved.