A user uploads a file on page 1 and the site redirects them to page 2 where they can click a button which triggers the service. I’m trying to create a unique URL for each user upload and I know the error has to do with the {% url 'initiate_transcription' session_id %}
in HTML page 2 form but i’m not sure what to change. Here is the code:
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("", views.transcribeSubmit, name = "transcribeSubmit"),
path("init-transcription/<str:session_id>/", views.initiate_transcription, name = "initiate_transcription"),
]
views.py:
@csrf_protect
def transcribeSubmit(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
uploaded_file = request.FILES['file']
fs = FileSystemStorage()
filename = fs.save(uploaded_file.name, uploaded_file)
request.session['uploaded_file_name'] = filename
request.session['uploaded_file_path'] = fs.path(filename)
session_id = str(uuid.uuid4())
request.session['session_id'] = session_id
# Render the 'transcribe-complete.html' template to a string
return JsonResponse({'redirect': reverse('initiate_transcription', args=[session_id])})
else:
else:
form = UploadFileForm()
@csrf_protect
def initiate_transcription(request, session_id):
if request.method == 'POST':
try:
# get the file's name and path from the session
file_name = request.session.get('uploaded_file_name')
file_path = request.session.get('uploaded_file_path')
audio_language = request.POST.get('audio_language')
output_file_type = request.POST.get('output_file_type')
if file_name and file_path:
with open(file_path, 'rb') as f:
path_string = f.name
transcript = transcribe_file(path_string,audio_language, output_file_type )
file_extension = ('.' + (str(file_name).split('.')[-1]))
transcript_name = file_name.replace(file_extension, f'.{output_file_type}')
transcript_path = file_path.replace((str(file_path).split('\')[-1]), transcript_name)
# Save transcript to a file
if os.path.exists(transcript_path):
file_location = transcript_path
rawdata = open(file_location, 'rb').read(1000)
result = chardet.detect(rawdata)
charenc = result['encoding']
with open(file_location, 'r', encoding=charenc) as f:
file_data = f.read()
transcribed_doc = TranscribedDocument(
audio_file=file_path,
output_file=transcript_path
)
transcribed_doc.save()
# Create a FileResponse
response = HttpResponse(file_data, content_type='text/plain; charset=utf-8')#text/plain
response['Content-Disposition'] = 'attachment; filename="' + transcript_name + '"'
return response
else:
return JsonResponse({'status': 'error', 'error': 'No file uploaded'})
except Exception as e:
error_message = f"Error occurred: {e}"
return render(request, 'transcribe/transcribe-complete.html')
def transcribe_file(path, audio_language, output_file_type ):
#transcription logic
HTML page1:
<form method="post" action="{% url 'transcribeSubmit' %}" enctype="multipart/form-data" >
{% csrf_token %}
<label for="transcribe-file" class="transcribe-file-label">
...
</form>
HTML page2:
<form id="initiate-transcription-form" method="post" action="{% url 'initiate_transcription' session_id %}" enctype="multipart/form-data">
{% csrf_token %}
...
</form
JS page1:
const fileInput = document.querySelector('#transcribe-file');
fileInput.addEventListener('change', function (event) {
if (event.target.files.length > 0) {
console.log(fileInput.value);
const fileName = event.target.value;
const fileExtension = fileName.split('.').pop().toLowerCase();
const allowedExtensions = ['m4a', 'wav', 'mp3', 'mpeg', 'mp4', 'webm', 'mpga', 'ogg', 'flac'];
if (!allowedExtensions.includes(fileExtension)) {
const uploadField = document.querySelector('.transcribe-file-label');
const originalLabelText = uploadField.innerHTML;
uploadField.style.color = '#ad0f0f';
uploadField.textContent = 'Invalid file type. Please try again';
setTimeout(function () {
uploadField.style.color = '';
uploadField.innerHTML = originalLabelText;
// Clear the file input field
fileInput.value = '';
return;
}, 5000);
} else {
const form = document.querySelector('form');
const xhr = new XMLHttpRequest();
const formData = new FormData(form);
xhr.open('POST', form.action);
xhr.upload.onprogress = function (event) {
if (event.lengthComputable) {
let percentComplete = (event.loaded / event.total) * 100;
let progressBar = document.getElementById('myBar');
progressBar.style.width = percentComplete + '%';
console.log('Upload progress: ' + percentComplete + '%');
}
};
xhr.onload = function () {
if (xhr.status == 200) {
console.log('Upload complete');
const response = JSON.parse(xhr.responseText);
// Update the content of the current page with the HTML from the server
if (response.redirect) {
window.location.href = response.redirect;
}
//document.body.innerHTML = response.html;
} else {
console.error('Upload failed');
}
};
xhr.send(formData);
}
}
});
Here is the error:
NoReverseMatch at /transcribe/init-transcription/854eae4d-3167-4e45-8b17-20a14b142aad/
Reverse for 'initiate_transcription' with arguments '('',)' not found. 1 pattern(s) tried: ['transcribe/init\-transcription/(?P<session_id>[^/]+)/\Z']
I can provide the traceback if necessary.
2
Answers
I guess you need to access the id from your session in the template:
The error you are encountering is due to
session_id
variable being empty when you attempt to use it in the{% url 'initiate_transcription' session_id %}
template tag in your HTML template on page 2. The error message,Reverse for 'initiate_transcription' with arguments '('',)' not found
, indicates that the URL template tag is not able to reverse the URL becausesession_id
is empty.Here’s the relevant part of your HTML page 2:
To resolve this issue, you should ensure that the
session_id
is correctly passed to your HTML template when you render it. In your view, when you render the template, make sure to include thesession_id
in the template context like this:This will make
session_id
available in your HTML template, and it can be used to construct the URL correctly.So, your HTML page 2 should look like this:
Make sure to pass the
session_id
to the template context when you render this template in your view. This should resolve theNoReverseMatch
error.