Ajax 如何使用动态 Django 下拉列表?
How can Ajax work with a dynamic Django dropdown list?
我正在制作这个需要 2 个地址的小型网络应用程序,使用 google 地图计算距离,并根据车辆的 mpg 评级计算汽油成本。一切都已完成,除了我认为最适合 AJAX.
的最后一部分
我有 3 个列表(年份、品牌、型号),我需要根据汽车的年份和品牌来限制车型列表。选择后,我有一个按钮,一旦单击,将验证它是否是数据库中的有效车辆,并提取车辆的 mpg 评级以对其进行一些基本数学运算。
问题是我真的不知道如何解决这个问题。在过去的几个小时里,我搜索了一些查询,我得到了很多与模型表单和 Django 选择字段相关的东西,如果不需要的话,我不想进入。我的想法是只更改 innerText/value,并根据我的 django 数据库检查它。
我也从 SO 那里看到了这个答案:
How do I integrate Ajax with Django applications?
对此我有点困惑。如果我理解正确,AJAX GET 请求将提取 javascript 对象中的数据,就像我作为用户访问 url 一样。这是否意味着我可以创建另一个 html 模板和 post 数据库中的每辆车到我可以从中提取信息并创建动态列表的页面?
寻找最直接的方法来使用 ajax 动态生成我的列表并使用我的数据库验证年份、品牌和型号,然后 return 汽车的 mpg。
models.py:
class Car(models.Model):
year = models.IntegerField(default=0)
make = models.CharField(max_length=60)
model = models.CharField(max_length=60)
mpg = models.IntegerField(default=0)
def __str__(self):
return ("{0} {1} {2}".format(self.year, self.make, self.model))
views.py:(目前只是列出所有车辆,无法现场核实车辆)
def index(request):
context_dic = {}
car_list = Car.objects.order_by('make')
car_list_model = Car.objects.order_by('model')
context_dic['car_list'] = car_list
context_dic['years'] = []
context_dic['makes'] = []
context_dic['models'] = []
for year in range(1995, 2016):
context_dic['years'].append(year)
for make in car_list:
if make.make not in context_dic['makes']:
context_dic['makes'].append(make.make)
else:
continue
for model in car_list_model:
if model.model not in context_dic['models']:
context_dic['models'].append(model.model)
else:
continue
return render(request, 'ConverterApp/index.html', context_dic)
html:(品牌和型号 x3)
<div id="specifics">
<div class="dropdown" id="year-dropdown">
<button class="btn btn-default dropdown-toggle" type="button"
id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Year
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
{% for year in years %}
<li><a href="#">{{ year }}</a></li>
{% endfor %}
</ul>
</div>
javascript:(现在只是显示值,无法与数据库验证)
$('#calculate').on('click', function ()
{
$(this).siblings()[0].textContent = (
document.getElementById("dropdownMenu1").textContent
+ " " + document.getElementById("dropdownMenu2").textContent
+ " " + document.getElementById("dropdownMenu3").textContent
+ " " + document.getElementById("specifics-gas").value
)
});
});
//this part changes the year, make, model to what the user selects //from the list
$('li').on('click', function () {
$(this).parent().siblings()[0].innerHTML = this.innerHTML
//console.log(this.textContent)
});
我不确定你对什么感到困惑。你为什么要把每辆车都放在一个页面上?当你构建一个普通的非 Ajax 页面时,你通过 URL 传递一些数据 - 例如数据库对象的 slug 或 ID,你查询数据库中的特定对象,并且 return 它的数据通过 HTML 模板。
完全相同的逻辑适用于 Ajax,只是您可能不想要 HTML 模板;直接returnJSON就可以了,JS容易理解
我会选择 REST 服务,例如 Django Rest Framework,然后使用 jquery 自动填充下拉列表。
如果安装 REST 服务很麻烦,您可以编写几个视图以获取 json 格式的数据...
例如,如果您在 /myapp/api 中有 REST 服务,您可以像这样填充汽车:
$.ajax({
url: "/myapp/api/cars?format=json",
dataType: "json",
success: function( data ) {
var makes=[];
for (var i in data) {
car = data[i];
if (makes.indexOf(car.make) < 0){ // avoid duplicate brands
makes.push(car.make);
$('#makeselect').append($('<option>', {
value: car.id,
text: car.make
}));
}
}
}
});
然后,在 "make" 选择器更改时附加一个处理程序,并使用另一个 REST 调用相应地填充模型和年份,例如 /myapp/api/cars?make=Ford
假设您必须在 drop-down 中填充所有品牌名称的静态列表,并且应该根据第一个中的选择填充第二个下拉列表。
假设两个简单的 Django 模型定义 Brands 和 Showrooms.
Views.py
class YourView(TemplateView):
template_name = 'template.html'
def get_context_data(self, **kwargs):
brands = Brands.objects.all()
context = super(YourView, self).get_context_data(**kwargs)
context.update({'brands': brands})
return context
def get_showrooms(request, **kwargs):
brand = Brands.objects.get(id=kwargs['brand_id'])
showroom_list = list(brand.showrooms.values('id', 'name'))
return HttpResponse(simplejson.dumps(showroom_list), content_type="application/json"
HTML
<label>Select Brand</label>
<select id="brands" name="brands" class="form-control">
<option value="">Select Brand</option>
{% for brand in brands %}
<option id="{{ brand.id }}" value="{{ brand.id }}">
{{ brand.name }}
</option>
{% endfor %}
</select>
<label>Select Showrroom</label>
<div id="showroom_list">
<select name="showrooms" class="form-control">
</select>
</div
Ajax
$('select[name=brands]').change(function(){
brand_id = $(this).val();
request_url = '/sales/get_showrooms/' + brand_id + '/';
$.ajax({
url: request_url,
success: function(data){
$.each(data, function(index, text){
$('select[name=showrooms]').append(
$('<option></option>').val(index).html(text)
);
};
});
您可以在 request_url 中进行 RESTful 调用。
您可以根据第二个中的选择进一步填充第三个下拉列表,依此类推。此外,您还可以访问所选选项并执行其他操作。
chosen plugin 可以帮助您优化下拉菜单。
我正在制作这个需要 2 个地址的小型网络应用程序,使用 google 地图计算距离,并根据车辆的 mpg 评级计算汽油成本。一切都已完成,除了我认为最适合 AJAX.
的最后一部分我有 3 个列表(年份、品牌、型号),我需要根据汽车的年份和品牌来限制车型列表。选择后,我有一个按钮,一旦单击,将验证它是否是数据库中的有效车辆,并提取车辆的 mpg 评级以对其进行一些基本数学运算。
问题是我真的不知道如何解决这个问题。在过去的几个小时里,我搜索了一些查询,我得到了很多与模型表单和 Django 选择字段相关的东西,如果不需要的话,我不想进入。我的想法是只更改 innerText/value,并根据我的 django 数据库检查它。
我也从 SO 那里看到了这个答案:
How do I integrate Ajax with Django applications?
对此我有点困惑。如果我理解正确,AJAX GET 请求将提取 javascript 对象中的数据,就像我作为用户访问 url 一样。这是否意味着我可以创建另一个 html 模板和 post 数据库中的每辆车到我可以从中提取信息并创建动态列表的页面?
寻找最直接的方法来使用 ajax 动态生成我的列表并使用我的数据库验证年份、品牌和型号,然后 return 汽车的 mpg。
models.py:
class Car(models.Model):
year = models.IntegerField(default=0)
make = models.CharField(max_length=60)
model = models.CharField(max_length=60)
mpg = models.IntegerField(default=0)
def __str__(self):
return ("{0} {1} {2}".format(self.year, self.make, self.model))
views.py:(目前只是列出所有车辆,无法现场核实车辆)
def index(request):
context_dic = {}
car_list = Car.objects.order_by('make')
car_list_model = Car.objects.order_by('model')
context_dic['car_list'] = car_list
context_dic['years'] = []
context_dic['makes'] = []
context_dic['models'] = []
for year in range(1995, 2016):
context_dic['years'].append(year)
for make in car_list:
if make.make not in context_dic['makes']:
context_dic['makes'].append(make.make)
else:
continue
for model in car_list_model:
if model.model not in context_dic['models']:
context_dic['models'].append(model.model)
else:
continue
return render(request, 'ConverterApp/index.html', context_dic)
html:(品牌和型号 x3)
<div id="specifics">
<div class="dropdown" id="year-dropdown">
<button class="btn btn-default dropdown-toggle" type="button"
id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Year
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
{% for year in years %}
<li><a href="#">{{ year }}</a></li>
{% endfor %}
</ul>
</div>
javascript:(现在只是显示值,无法与数据库验证)
$('#calculate').on('click', function ()
{
$(this).siblings()[0].textContent = (
document.getElementById("dropdownMenu1").textContent
+ " " + document.getElementById("dropdownMenu2").textContent
+ " " + document.getElementById("dropdownMenu3").textContent
+ " " + document.getElementById("specifics-gas").value
)
});
});
//this part changes the year, make, model to what the user selects //from the list
$('li').on('click', function () {
$(this).parent().siblings()[0].innerHTML = this.innerHTML
//console.log(this.textContent)
});
我不确定你对什么感到困惑。你为什么要把每辆车都放在一个页面上?当你构建一个普通的非 Ajax 页面时,你通过 URL 传递一些数据 - 例如数据库对象的 slug 或 ID,你查询数据库中的特定对象,并且 return 它的数据通过 HTML 模板。
完全相同的逻辑适用于 Ajax,只是您可能不想要 HTML 模板;直接returnJSON就可以了,JS容易理解
我会选择 REST 服务,例如 Django Rest Framework,然后使用 jquery 自动填充下拉列表。
如果安装 REST 服务很麻烦,您可以编写几个视图以获取 json 格式的数据...
例如,如果您在 /myapp/api 中有 REST 服务,您可以像这样填充汽车:
$.ajax({
url: "/myapp/api/cars?format=json",
dataType: "json",
success: function( data ) {
var makes=[];
for (var i in data) {
car = data[i];
if (makes.indexOf(car.make) < 0){ // avoid duplicate brands
makes.push(car.make);
$('#makeselect').append($('<option>', {
value: car.id,
text: car.make
}));
}
}
}
});
然后,在 "make" 选择器更改时附加一个处理程序,并使用另一个 REST 调用相应地填充模型和年份,例如 /myapp/api/cars?make=Ford
假设您必须在 drop-down 中填充所有品牌名称的静态列表,并且应该根据第一个中的选择填充第二个下拉列表。
假设两个简单的 Django 模型定义 Brands 和 Showrooms.
Views.py
class YourView(TemplateView):
template_name = 'template.html'
def get_context_data(self, **kwargs):
brands = Brands.objects.all()
context = super(YourView, self).get_context_data(**kwargs)
context.update({'brands': brands})
return context
def get_showrooms(request, **kwargs):
brand = Brands.objects.get(id=kwargs['brand_id'])
showroom_list = list(brand.showrooms.values('id', 'name'))
return HttpResponse(simplejson.dumps(showroom_list), content_type="application/json"
HTML
<label>Select Brand</label>
<select id="brands" name="brands" class="form-control">
<option value="">Select Brand</option>
{% for brand in brands %}
<option id="{{ brand.id }}" value="{{ brand.id }}">
{{ brand.name }}
</option>
{% endfor %}
</select>
<label>Select Showrroom</label>
<div id="showroom_list">
<select name="showrooms" class="form-control">
</select>
</div
Ajax
$('select[name=brands]').change(function(){
brand_id = $(this).val();
request_url = '/sales/get_showrooms/' + brand_id + '/';
$.ajax({
url: request_url,
success: function(data){
$.each(data, function(index, text){
$('select[name=showrooms]').append(
$('<option></option>').val(index).html(text)
);
};
});
您可以在 request_url 中进行 RESTful 调用。
您可以根据第二个中的选择进一步填充第三个下拉列表,依此类推。此外,您还可以访问所选选项并执行其他操作。 chosen plugin 可以帮助您优化下拉菜单。