как добавить AJAX на веб-страницу Django - PullRequest
0 голосов
/ 30 января 2019

Я работаю над приложением django.Это приложение содержит две формы.В первой форме ( image_form ) пользователь может загрузить изображение.Во второй форме ( image_description ) пользователь может заполнить некоторое описание об изображении.когда изображение загружено в первую форму, на изображении запускается классификатор изображений, который пытается заполнить части формы image_description.После отправки второй формы элемент отображается на новой странице ( item_list ).Это urlpatterns для приложения.

urls.py

urlpatterns = [
    path('', views.index, name='home'),
    path('accounts/', include('django.contrib.auth.urls')),

    path('signup/', views.signup, name='signup'),

    path('items/', views.item_list, name='item_list'),
    path('items/upload/description/', views.upload_item, name='upload_item'),
    path('items/<int:pk>/', views.delete_item, name='delete_item'),
    path('items/upload/image_classification/', views.image_classification, name='image_classification'),
]

здесь item_list - страница, на которой отображаются все элементы.Эта страница отображается после отправки формы image_description.

upload_item Страница содержит обе формы.

image_classification запускается, когда кнопка загрузки изображения впервая форма нажата.Это происходит на странице upload_item.

views.py

def item_list(request):
    items = Item.objects.all()

    return render(request, 'item_list.html', {'items':items})

def upload_item(request):
    if request.method == 'POST':
        form_des = ItemForm(request.POST, request.FILES)

        if form_des.is_valid():
            form_des.save()
            return redirect('item_list')
    else:
        form_des = ItemForm()

        return render(request, 'upload_item.html', {'form_des': form_des})

def image_classification(request):

    form_des = ItemForm()

    if request.method == 'POST':
        if 'file' in request.FILES:
            handle_uploaded_file(request.FILES['file'], str(request.FILES['file']))

            img = np.expand_dims(cv2.resize(cv2.imread(os.path.join('./media/item/img/', str(request.FILES['file']))), (170, 100)), axis=0)
            cat_prediction = cat_classifier.predict_classes(img)[0]
            pattern_prediction = pat_classifier.predict_classes(img)[0]

            form_des.fields['title'].widget.attrs['value'] = cat_prediction
            form_des.fields['pattern'].widget.attrs['value'] = pattern_prediction
            form_des.fields['user'].widget.attrs['value'] = request.user
            form_des.fields['user'].widget.attrs['readonly'] = True

            return render(request, 'upload_item.html', {'form_des': form_des})

    else:
        return redirect('upload_item')

upload_item.html template

<div class="container">
  <div class="row justify-content-center">
    <div class="col-7">
      <center>
        <h2>Upload image</h2>

        <!-- <div class="row justify-content-center"> -->
            <div class="upload-btn-wrapper">
              <form action="{% url 'image_classification' %}" method="POST" enctype="multipart/form-data" data-url="image_classification/" class="my_form">
                {% csrf_token %}
                <input type="file" name="file" id="file" class="inputfile" multiple/>
                <label for="file" class="btn btn-outline-dark btn-lg mt-5 select">Choose a file</label>

                 <input class='btn btn-primary btn-lg btn-block upload_image_button' type="submit" value="Upload image" disabled/>
              </form>
            </div>
        <!-- </div> -->
        <center>
          <p class='font-weight-bold mt-5 mb-5 text-danger'>Step: 1 of 2</p>
        </center>

        <div class="separation"></div>

        <h2>Item description</h2>
      </center>
      <div class="card mb-2 mt-3">
        <div class="card-body">
          <form method="post" enctype="multipart/form-data" action="{% url 'upload_item' %}" id='item_des'>
            {% csrf_token %}
            {{form_des.title|as_crispy_field}}
            {{form_des.pattern|as_crispy_field}}
            {{form_des.color|as_crispy_field}}
            {{form_des.user|as_crispy_field}}
            <button type="submit" class='btn btn-primary btn-lg btn-block save_btn'>Save item</button>
          </form>
        </div>
      </div>
      <center>
        <p class='font-weight-bold mt-2 mb-5 text-danger'>Step: 2 of 2</p>
      </center>
    </div>
  </div>
</div>

Моя проблема заключается в том, что при нажатии кнопки загрузки изображения в первой форме URL-адрес изменяется с items/upload/description/ на items/upload/image_classification/, и страница перезагружается с автоматически заполненными разделами во второй форме.

Я хочу использовать AJAX для автоматического заполнения второй формы без перезагрузки страницы, но не уверен, как это сделать.Я следовал нескольким учебникам, но не смог этого добиться.

Пожалуйста, помогите мне

Спасибо

[EDIT1] Основываясь на ответе Адиля Сиддики, я внес несколько изменений в views.py

views.py

def image_classification(request):

    form_des = ItemForm()
    user =str(request.user)

    if request.method == 'POST':
        if 'file' in request.FILES:
            handle_uploaded_file(request.FILES['file'], str(request.FILES['file']))

            img = np.expand_dims(cv2.resize(cv2.imread(os.path.join('./media/item/img/', str(request.FILES['file']))), (170, 100)), axis=0)
            cat_prediction = cat_classifier.predict_classes(img)[0]
            pattern_prediction = pat_classifier.predict_classes(img)[0]

            form_des.fields['title'].widget.attrs['value'] = cat_prediction
            form_des.fields['pattern'].widget.attrs['value'] = pattern_prediction
            form_des.fields['user'].widget.attrs['value'] = request.user
            form_des.fields['user'].widget.attrs['readonly'] = True

            context = {
                'tops_prediction'   :tops_prediction,
                'pattern_prediction':pattern_prediction,
                'user'            :user,
            }

            return HttpResponse(json.dumps(context))

    else:
        return redirect('upload_item')

Как получить доступ к этому контексту из fillImageDescriptionText в jquery и автоматически заполнить вторую формуна странице upload_item?

[EDIT-2] снимок экрана с выводом после использования обновленного ответа enter image description here

1 Ответ

0 голосов
/ 30 января 2019

Вы можете предотвратить событие по умолчанию, которое происходит при отправке формы.Предположим, что ваша форма классификации изображений имеет идентификатор image-classify-form, тогда:

$("#image-classify-form").submit(function(event) {
    event.preventDefault();
    imageClassifyAjax();
}

, где ваша функция imageClassifyAjax делает это (ранее я забыл создать объект FormData в строке 2, которая вызывалаСбой запроса POST) :

function imageClassifyAjax() {
    let $form = $("#image-classify-form");
    let form_data = new FormData($form[0]);
    $.ajax({
        url: $form.attr('action'),
        type: $form.attr('method'),
        data: form_data,
        processData: false,
        contentType: false,
        dataType: 'json',
        success: function (data) {
            fillImageDescriptionText(data);
        },
        error: function (xhr) {
            console.log("Something went wrong: " + xhr.responseText);
        }
    });
}

, а fillImageDescriptionText использует данные json, возвращаемые представлением, чтобы заполнить форму для описания изображения.Таким образом, вы должны изменить то, что делает ваш взгляд на метод POST.Вы должны вернуть HttpResponse вместо шаблона визуализации:

import json
from django.http import HttpResponse

def image_classification(request):

    form_des = ItemForm()

    if request.method == 'POST':
        ...
        ...
        return HttpResponse(json.dumps({'title': cat_prediction, 'pattern': pattern_prediction, 'user': request.user.email}))

fillImageDescriptionText получает этот объект json в качестве входных данных, поэтому вы можете в основном:

function fillImageDescriptionText(data) {
    $("#item_des #id_title").val(data.title);
    $("#item_des #id_pattern").val(data.pattern);
    $("#item_des #id_user").val(data.user);
    $("#item_des #id_user").prop('readonly', true);
}

где id_ это идентификатор, сгенерированный для элементов хрустящими формами django или любым другим пакетом, который вы используете для форм.В основном это префикс с «id_».Вы можете проверить это, проверив элементы из браузера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...