Как 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.

Другие вопросы по тегам