jeffreyb
jeffreyb

Reputation: 163

make some django/wagtail files private

Is there a way to make some files unaccessible via direct url? For example, an image appears on a page but the image location doesn't work on it's own.

Upvotes: 0

Views: 365

Answers (1)

Robert Townley
Robert Townley

Reputation: 3574

How Things Normally Work By default, all static and media files are served up from the static root and media root folders. A good practice is to have NGINX or Apache route to these, or to use something like Django Whitenoise to serve up static files.

In production, you definitely don't want to have the runserver serving up these files because 1) That doesn't scale well, 2) It means you're running in DEBUG mode on production which is an absolute no-no.

Protecting Those Files You can keep this configuration for most files that you don't need to protect. Instead, you can serve up files of your own within Django from a different filepath. Use the upload_to parameter of the filefield to specify where you want those files to live. For example,

protectedfile = models.FileField(upload_to="protected/")
publicfile = models.FileField(upload_to="public/")

Then in NGINX make your block direct to /var/www/myproject/MEDIAROOT/public instead. That will enable you to continue serving up public files.

Meanwhile, for the protected files, those can be served up by the view with:

def view_to_serve_up_docs(request, document_id):
    my_doc = MyDocumentModel.objects.get(id=document_id)

    # Do some check against this user
    if request.user.is_authenticated():
        response = FileResponse(my_doc.privatefile)
        response["Content-Disposition"] = "attachment; filename=" + my_doc.privatefile.name
    else:
        raise Http404()
    return response

And link to this view within your templates

<a href='/downloadFileView/12345'>Download File #12345 Here!</a>

Reference More about the FileResponse object: https://docs.djangoproject.com/en/1.11/ref/request-response/#fileresponse-objects

Upvotes: 1

Related Questions