protecting user uploaded files django

后端 未结 1 1833
孤街浪徒
孤街浪徒 2021-02-02 04:26

How can I allow users to upload files to their own, user designated folder, and only see files that they have uploaded? I am using django file-transfer. Currently it gives me a

1条回答
  •  被撕碎了的回忆
    2021-02-02 05:11

    uploadmodel_file_upload_to returns a relative path. To build the full path, django prepends settings.MEDIA_ROOT. MEDIA_ROOT is supposed to be public readable.

    So we want to save the file outside MEDIA_ROOT. Add something like this to settings.py:

    import os.path
    PROJECT_ROOT=os.path.abspath(os.path.dirname(__file__))
    PROTECTED_MEDIA_ROOT=os.path.join(PROJECT_ROOT, 'protected_uploads')
    

    Now you can update uploadmodel_file_upload_to to return an absolute path:

    def uploadmodel_file_upload_to(instance, filename):
        return '%s/%s/%s' % (settings.PROTECTED_MEDIA_ROOT, instance.user.username,
            filename)
    

    Now that the files are saved in /project/path/protected_uploads, we need to add a view to serve it, for example:

    import os 
    import mimetypes
    
    from django import shortcuts
    from django import http
    from django.conf import settings
    from django.views.static import was_modified_since
    from django.utils.http import http_date
    
    from .models import *
    
    def serve_upload(request, upload_id):
        upload = shortcuts.get_object_or_404(UploadModel, pk=upload_id)
        fullpath = upload.file.path
    
        if request.user != upload.user:
            return http.HttpResponseForbidden()
    
        statobj = os.stat(fullpath)
        mimetype, encoding = mimetypes.guess_type(fullpath)
        mimetype = mimetype or 'application/octet-stream'
        if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'),
                                  statobj.st_mtime, statobj.st_size):
            return http.HttpResponseNotModified(mimetype=mimetype)
        response = http.HttpResponse(open(fullpath, 'rb').read(), mimetype=mimetype)
        response["Last-Modified"] = http_date(statobj.st_mtime)
        response["Content-Length"] = statobj.st_size
        if encoding:
            response["Content-Encoding"] = encoding
        return response
    

    And a URL:

    url(r'serve_upload/(?P\d+)/$', 'serve_upload'),
    

    0 讨论(0)
提交回复
热议问题