Передача данных во фреймворк django с помощью javascript (без jquery)

У меня есть выпадающий список, который я получил из загруженного CSV-файла из Django, который я хочу передать обратно в другое представление Django с помощью javascript при выборе значения. Я продолжаю получать 404 ошибку (index.js:9 POST http://127.0.0.1:8000/gui_app/%7B%%20url%20%22get_selection%22%20%%7D 404 (Not Found) (anonymous) @ index.js:9 ), когда я нажимаю на кнопку select после того, как я выбрал значение из выпадающего списка. Насколько я понял, прочитав сообщение об ошибке, проблема, похоже, возникает из-за того, что javascript не может правильно отобразить url. Как правильно передать url в javascript, чтобы javascript распознал его и передал данные в представление? Вот мой код ниже

index.js


let signalSelectButton = document.getElementById("signalSelectButton")
const url = loacation.href('/get_selection/')

signalSelectButton.addEventListener("click", function() {
  console.log("clicked")
  const selectedValue = document.getElementById("signalSelect").value
  console.log(selectedValue)
  
  fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-CSRFToken': '{{ csrf_token }}'
    },
    body: JSON.stringify({selected_value: selectedValue})
    })
    .then(response => {
      if (!response.ok) {
        throw new Error('Network response was not ok')
      }
      return response.json()
    })
    .then(data => {
      console.log(data)
      document.getElementById('response-message').innerText = data.message
  })
    .catch(error => {console.error('Error:', error)})
})

views.py

from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.conf import settings
from django.core.files.storage import FileSystemStorage
from .forms import SigFileForm
from django.contrib import messages
from django.views.decorators.csrf import csrf_exempt
import os
import pandas as pd

# Create your views here.
def index(request):
    return HttpResponse("Hello, world!")
        
def model_upload(request):
    # return render(request, 'model_upload.html')
    if request.method == 'POST':
        form = SigFileForm(request.POST, request.FILES)
        if form.is_valid():
            sigfile = request.FILES['file']
            sigfile_name = sigfile.name
            sigfile_size = sigfile.size
            instance = form.save()
            sigfile_url = instance.file.url
            choices = populate_dropdown(sigfile_url)
            messages.success(request, 'File uploaded successfully!')
            return render(request, 'model_upload.html', {'form': form, 'choices': choices})
        else:
            return render(request, 'model_upload.html', {'form': form})
    else:
        form = SigFileForm()
        return render(request, 'model_upload.html', {'form': form})
        
def populate_dropdown(file_url):
    file_path = os.path.join(settings.MEDIA_ROOT, file_url.lstrip('/media/'))
    if os.path.exists(file_path):
        df = pd.read_csv(file_path, sep = ',', index_col = 'Time,ms')
        choices =  df.columns.values.tolist()
        return choices
    else:
        print(f'File does not exist: {file_path}')
        return []
        
@csrf_exempt
def get_selection(request):
    if request.method == 'POST':
        selected_value = request.POST.get('selected_value')
        return JsonResponse({'message': f'You selected: {selected_value}'})
    else:
        return JsonResponse({'message': ''})

urls.py

from django.urls import path

from . import views

urlpatterns = [
    path("", views.index, name = "index"),
    path("simple_upload", views.simple_upload, name = "simple_upload"),
    path("model_upload", views.model_upload, name = "model_upload"),
    path("get_selection", views.get_selection, name = "get_selection"),
]

В самом начале расположение стартпельта было неправильным const url = loacation.href('/get_selection/'), но я полагаю, что это может быть опечаткой, которую вы заметили.

Так как вы просто хотите сделать запрос к конечной точке, контролируемой Django, используйте встроенный тег шаблона {% url "get_selection" %} для определения URL для установки, как указано в документации по встроенному шаблону здесь https://docs.djangoproject.com/en/5.1/ref/templates/builtins/#url

Если вы используете константу "url" только в одном месте, то я бы предложил не использовать ее вообще и изменить вашу выборку на следующую fetch("{% url "get_selection" %}", { ...

Поскольку данные являются JSON, а не данными формы, они требуют другой обработки. При использовании декоратора @csrf_exempt нет необходимости включать заголовок 'X-CSRFToken'. Также можно использовать атрибуты данных вместе с обратным разрешением URL в Django. Вот минимальный пример:

<body>
<label for="cars">Choose a car:</label>

<select name="cars" id="signalSelectBox" data-url="{% url 'get_selection' %}">
    <option value="volvo">Volvo</option>
    <option value="saab">Saab</option>
    <option value="mercedes">Mercedes</option>
    <option value="audi">Audi</option>
</select>
<button id="signalSelectButton">select</button>
</body>

script.js

const signalSelectButton = document.getElementById("signalSelectButton");
const signalSelectBox = document.getElementById("signalSelectBox");
const url = signalSelectBox.dataset.url;

signalSelectButton.addEventListener("click", sendRequest);

async function sendRequest() {
    let selectedValue = signalSelectBox.value
    try {
        const response = await fetch(url, {
            method: "POST",
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({selected_value: selectedValue})
        })

        const data = await response.json();

        console.log(data.message);

    } catch (error) {
        console.log(error)
    }

}

views.py

import json

@csrf_exempt
def get_selection(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        selected_value = data['selected_value']
        return JsonResponse({'message': f'You selected: {selected_value}'})
    else:
        return JsonResponse({'message': ''})
Вернуться на верх