为什么我的Django视图返回“Reverse for 'initiate_transcription' with arguments '('',)' not found '?

aelbi1ox  于 2023-10-21  发布在  Go
关注(0)|答案(2)|浏览(125)

用户在第1页上传文件,网站会将其重定向到第2页,在那里他们可以点击触发服务的按钮。我试图为每个用户上传创建一个唯一的URL,我知道错误与HTML页面2表单中的{% url 'initiate_transcription' session_id %}有关,但我不确定要更改什么。代码如下:
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页面1:

<form method="post" action="{% url 'transcribeSubmit' %}" enctype="multipart/form-data" >
                            {% csrf_token %}
                            <label for="transcribe-file" class="transcribe-file-label">
                                ...
</form>

HTML第2页:

<form id="initiate-transcription-form" method="post" action="{% url 'initiate_transcription' session_id %}" enctype="multipart/form-data">
                    {% csrf_token %}
                   
...
</form

JS第1页:

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);
    }
}
});

下面是错误:

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']

如果有必要,我可以提供追踪。

ct3nt3jp

ct3nt3jp1#

我猜你需要从模板中的会话访问id:

...on="{% url 'initiate_transcription' request.session.session_id %}" enctype="mul...
sxpgvts3

sxpgvts32#

您遇到的错误是由于session_id变量是空的,当您尝试在第2页HTML模板的{% url 'initiate_transcription' session_id %}模板标记中使用它时。错误消息Reverse for 'initiate_transcription' with arguments '('',)' not found表示URL模板标记无法反转URL,因为session_id为空。
以下是HTML页面的相关部分2:

<form id="initiate-transcription-form" method="post" action="{% url 'initiate_transcription' session_id %}" enctype="multipart/form-data">
    {% csrf_token %}
    <!-- Form -->
</form>

要解决此问题,您应该确保在呈现session_id时将其正确传递给HTML模板。在你看来,当你渲染模板时,确保在模板上下文中包含session_id,如下所示:

return render(request, 'transcribe/transcribe-complete.html', {'session_id': request.session.session_id})

这将使session_id在您的HTML模板中可用,并且它可以用于正确构造URL。
所以,你的HTML页面2应该是这样的:

<form id="initiate-transcription-form" method="post" action="{% url 'initiate_transcription' session_id %}" enctype="multipart/form-data">
    {% csrf_token %}
    <!-- Form -->
</form>

在视图中呈现这个模板时,确保将session_id传递给模板上下文。这将解决NoReverseMatch错误。

相关问题