Search code examples
pythondjangoherokudownloaddjango-staticfiles

heroku django "file does not exist" when i try to download it from the server


I successfully deployed my app to heroku server but faced this problem when i try to download a file (like with <a href="{{object.file.url}}">Download</a>) django return "Page not found" with error "file 'app/.../.../{file}' does not exist" ("app" is not real app name. I don't know, where does it come from). Other static files (like with href="{% static "path/to/file" %}") work great. The same thing in the admin panel, when I go to the model instance, which stores the path to the file - the path is displayed, but nothing is downloaded from there. What should i do?


Solution

  • I found a solution to my problem. It was necessary to clarify above: I do not need a full-fledged separate server for media files like AWS S3, etc., because my project is just a demo. This is not a working project, so I needed to fix the problem in a way that would stay with local heroku storage. I solved this problem: I wrote a view, which returns a file via FileResponce.

    Code:

    # views.py
    # ... necessary imports
    
    class Download(View):
        def get(self, request, *args, **kwargs):
            file_name = self.kwargs.get('file_name')
            username = self.kwargs.get('username')
            file_path = os.path.join(settings.BASE_DIR, 'media', 'documents', f'user_{username}', file_name)
            if os.path.exists(file_path):
                return FileResponse(open(file_path, 'rb'))
            raise Http404
    
    # urls.py
    
    urlpatterns = [
        ...,
        path('download/<str:username>/<str:file_name>', Download.as_view(), name='graduateWork/download'),
        ...,
    
    
    # templatetags/file_name.py
    from django import template
    
    
    register = template.Library()
    
    
    @register.filter
    def get_file_name(fl: str):
        return fl.split('/')[-1]
    
    <a class='btn btn-success' style='text-decoration: none; color: white;' href="{% url 'graduateWork/download' username=document.publisher.username file_name=document.file.name|get_file_name %}">
        Скачать <img src="{% static 'download.png' %}" height='20px;' alt="скачать">
    </a>
    

    If you want stay with heroku local storage like me, use this solution.