Search code examples
pythondjangodjango-viewsdjango-urlsdjango-url-reverse

NoReverseMatch error for download file page


I am working on a django web application. Here the web app generates a pandas dataframe when a form is submitted. This dataframe is stored in the root directory. I have another view that is used for downloading the generated csv file. But when I redirect to the download page, I get a No reverse match error.

this is my code so far

def randomfilename(stringLength=8):
    lettersAndDigits = string.ascii_letters + string.digits
    return ''.join(random.choice(lettersAndDigits) for i in range(stringLength))

def generate_dataframe(request):
    if request.method == 'POST':
        ...
        df = pd.DataFrame(columns=cols)
        df['title'] = title_lst
        df['link'] = product_links[:1]

        fn = randomfilename()
        df.to_csv('./'+fn+'.csv')
        return redirect("download_file", filename = fn)

def download_file(request, filename):
    if request.method == 'POST':

        file_path = './'+filename

        file = open(file_path, 'r')
        mime_type, _ = mimetypes.guess_type(file_path)
        response = HttpResponse(file, content_type=mime_type)
        response['Content-Disposition'] = "attachment; filename=%s" % filename

        return response

project urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('scraper.urls')),
]

scraper urls.py

urlpatterns = [
    path('generate', views.generate_dataframe, name='generate_dataframe'),
    path('download/<filename>/', views.download_file, name='download_file'),
]

I know I am messing up the URL somewhere. But I am not sure how to rectify this problem. Please help me. Thanks in advance.


Solution

  • Try this:

    In your views

    from django.urls import reverse
    
    def generate_dataframe(request):
        ...
    return redirect(reverse('download_file', kwargs={'filename': fn}))
    

    In your urls.py:

    urlpatterns = [
        ...
        path('download/<str:filename>/', views.download_file, name='download_file'),
    ]
    

    In your template:

    {% url 'download_file' filename %}