1

I am using Django to build a webapp that will only be used locally. Before this I had very little direct experience with web development, Django and HTML.

I would like the user to be able to browse for files on his/her own machine, as is possible with <input type="file" [...]>. However, since the app will only be used locally and since some very large files will be involved, I only want access to the filepath - i.e. without uploading the file data itself - upon pressing submit.

Using Django's FileField class I was unable to bypass the file upload phase. I used custom upload filters (and confirmed that they were actually called), and tried raise SkipFile in a few different spots in them which is supposed to cancel uploading the file according to the documentation - as I understood it, at least.

I thought I'd cracked it by entering the HTML directly instead of using my dir_form from Django:

<form action="" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <!-- {{ dir_form }} -->
    <input type="file" id="docpicker" name="filepath">
    <input type="submit" value="Submit" name="file">
</form>

and I tried raise SkipFile at different points in the upload handler (the prints were to see in what order they were called):

class SkippingUploadHandler(FileUploadHandler):

    def handle_raw_input(self, input_data, META, content_length, boundary, encoding=None):
        print(1)
        raise SkipFile

    def new_file(self, *args, **kwargs):
        print(2)
        raise SkipFile

    def receive_data_chunk(self, raw_data, start):
        print(3)
        raise SkipFile

but these didn't help.

I would like the user to be able to browse in his/her own system, choose a file and press 'Submit'. On submitting, I would like only the filepath to be transferred and not the file contents, as is currently the case.

All help (and patience) greatly appreciated!

aybry
  • 316
  • 1
  • 7
  • If the "browser" you use is not runned as a local (installed in one way or the other) app you will never be able to get a file's local path. It would be a huge security risk. – Asons Apr 10 '19 at 11:43
  • Thanks. If using the webapp only via localhost counts as running my browser locally, then that is the case. I won't be running it on a server and only people with the source code itself will be able to execute it. – aybry Apr 10 '19 at 11:48
  • No, "localhost" is not a _local installed app_ so that won't work. – Asons Apr 10 '19 at 11:49
  • Hmm. Perhaps I'm missing something. If the app is only to be run locally, where is the security risk? Is it not possible to build a custom "browse" button that allows the user to select a file, and the filepath chosen is entered into a text field? – aybry Apr 10 '19 at 11:51
  • From the browsers perspective, it runs a "webpage", and whether it is served from a local or remote web server doesn't matter. An intruder could get access to that "webpage" and with that interact with other "webpages"/"webservers", hence becomes a risk. So the answer is, **no** you can't unless you install it as an app. – Asons Apr 10 '19 at 11:54
  • Looks like Django offers [FilePathField](https://docs.djangoproject.com/en/2.2/ref/models/fields/) for these situations. If that is too restrictive you have to look for other server-side file pickers like [Filer](https://github.com/divio/django-filer) – hsan Apr 10 '19 at 12:17
  • Thanks @hsan. I looked into FilePathField at the beginning but I think I wrote it off as a no-go and didn't look at it again. But it will probably be the best option unless Filer can save me! – aybry Apr 10 '19 at 12:30

0 Answers0