Как Ajax может работать с динамическим выпадающим списком Django?
Я делаю это маленькое веб-приложение, которое берет 2 адреса, вычисляет расстояние, используя карты Google, и рассчитывает стоимость газа на основе рейтинга транспортных средств на галлон. Все завершено, за исключением этой последней части, которая, я считаю, будет работать лучше всего с AJAX.
У меня есть 3 списка (год, марка, модель), и мне нужно, чтобы список моделей автомобилей был ограничен в зависимости от года и марки автомобиля. После выбора у меня есть кнопка, которая однажды нажала, проверит, является ли она действительным транспортным средством в базе данных, и вытянет рейтинг миль на галлон транспортного средства, чтобы выполнить некоторые основные математические операции.
Проблема в том, что я не знаю, как подойти к этой проблеме. За последние несколько часов я искал несколько запросов, и я получаю много вещей, связанных с модельными формами и полями выбора Django, в которые я не хочу входить, если мне не нужно. Моя идея состоит в том, чтобы просто изменить innerText / value и сравнить его с моей базой данных django.
Я также наткнулся на этот ответ от SO:
Как интегрировать Ajax с приложениями Django?
и я немного смущен этим. Если я правильно понимаю, запрос AJAX GET будет извлекать данные в объектах javascript так же, как если бы я посетил этот URL как пользователь. Означает ли это, что я мог бы просто создать другой HTML-шаблон и разместить каждый автомобиль в базе данных на той странице, с которой я могу извлечь информацию и создать свои динамические списки?
Ищите самый простой способ динамически генерировать мои списки с помощью ajax и проверять год, марку и модель с моей базой данных, которая затем возвращает 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)
});
3 ответа
Я хотел бы использовать REST-сервис, например Django Rest Framework, а затем использовать jquery для автоматического заполнения выпадающих списков.
Если установка службы REST - это хлопотно, вы можете написать пару представлений, чтобы получить данные в формате json...
Например, если у вас есть служба REST в /myapp/api, вы можете заполнить автомобили следующим образом:
$.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
Предположим, вам нужно заполнить статический список всех названий брендов в раскрывающемся списке, а второй раскрывающийся список должен быть заполнен на основе выбора в первом.
Предполагая две простые модели Django, определяющие бренды и выставочные залы.
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)
);
};
});
Вы можете сделать вызовы RESTful в request_url.
Вы можете дополнительно заполнить третий выпадающий список на основе выбора в секунду и так далее. Также вы можете получить доступ к выбранной опции и выполнить дальнейшие действия. Выбранный плагин может помочь вам в оптимизации ваших выпадающих.
Я не уверен, что вы смущены. Зачем тебе ставить каждую машину на страницу? Когда вы создаете обычную не-Ajax-страницу, вы передаете некоторые данные - например, слаг или идентификатор объекта базы данных - через URL-адрес, запрашиваете у базы данных этот конкретный объект и возвращаете ее данные через шаблон HTML.
Точно такая же логика применима к Ajax, за исключением того, что вам, вероятно, не нужен шаблон HTML; Вы можете просто вернуть JSON, что легко понять для JS.