Upload a File with Python

2019-02-06 19:39发布

问题:

I have an HTML form and I am using Python to generate a log file based on the input. I'd like to also be able to allow the user to upload an image if they choose. I can figure out how to manipulate it with Python once it's there, but I'm not sure how to get the image uploaded. This has most certainly been done before, but I'm having a hard time finding any examples. Can any of you point me in the right direction?

Basically, I'm using cgi.FieldStorage and csv.writer to make the log. I want to get an image from the user's computer and then save it to a directory on my server. I will then rename it and append the title to the CSV file.

I know there are a lot of options for this. I just don't know what they are. If anyone could direct me toward some resources I would be very appreciative.

回答1:

Since you said that your specific application is for use with the python cgi module, a quick google turns up plenty of examples. Here is the first one:

Minimal http upload cgi (Python recipe) (snip)

def save_uploaded_file (form_field, upload_dir):
    """This saves a file uploaded by an HTML form.
       The form_field is the name of the file input field from the form.
       For example, the following form_field would be "file_1":
           <input name="file_1" type="file">
       The upload_dir is the directory where the file will be written.
       If no file was uploaded or if the field does not exist then
       this does nothing.
    """
    form = cgi.FieldStorage()
    if not form.has_key(form_field): return
    fileitem = form[form_field]
    if not fileitem.file: return
    fout = file (os.path.join(upload_dir, fileitem.filename), 'wb')
    while 1:
        chunk = fileitem.file.read(100000)
        if not chunk: break
        fout.write (chunk)
    fout.close()

This code will grab the file input field, which will be a file-like object. Then it will read it, chunk by chunk, into an output file.

Update 04/12/15: Per comments, I have added in the updates to this old activestate snippet:

import shutil

def save_uploaded_file (form_field, upload_dir):
    form = cgi.FieldStorage()
    if not form.has_key(form_field): return
    fileitem = form[form_field]
    if not fileitem.file: return

    outpath = os.path.join(upload_dir, fileitem.filename)

    with open(outpath, 'wb') as fout:
        shutil.copyfileobj(fileitem.file, fout, 100000)


回答2:

The web frame work Pyramid has a good example. http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/forms/file_uploads.html

Here is my example code that I use with a working project.

    extension = os.path.splitext(request.POST[form_id_name].filename)[1]
    short_id = str(random.randint(1, 999999999))
    new_file_name =  short_id + extension
    input_file = request.POST[form_id_name].file
    file_path = os.path.join(os.environ['PROJECT_PATH'] + '/static/memberphotos/', new_file_name)

    output_file = open(file_path, 'wb')
    input_file.seek(0)
    while 1:
        data = input_file.read(2<<16)
        if not data:
            break
        output_file.write(data)
    output_file.close()