I have a dropdown list that I got from an uploaded CSV file from Django that I want to pass back to a different Django view with javascript when selected. I keep getting a 404 error (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
) when I click on the select
button after I choose a value from the dropdown. From what I understand reading the error message, the issue seems to be coming from javascript not being able to render the url the correct way. What’s the correct way to pass the url in javascript so that javascript recognizes it and passes the data to the view? Here’s my code below
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"),
]
2
Answers
To startspelt location wrong at the start
const url = loacation.href('/get_selection/')
but I expect that may be a typo you’ve noticed.That aside as you just want to make the request to an endpoint controlled by Django use the built-in template tag
{% url "get_selection" %}
to determine the URL to set, as reference by the built-in templatetag docs here https://docs.djangoproject.com/en/5.1/ref/templates/builtins/#urlIf you are only using the "url" constant in that one place then I’d suggest not using it at all and changing your fetch to be this
fetch("{% url "get_selection" %}", { ...
Since data is JSON and not form data it requires a different processing. While using
@csrf_exempt
decorator it is not necessary to include'X-CSRFToken'
header. Also, its possible to use data attributes together with Django’s reverse resolution of URLs. Here is a minimal example:script.js
views.py