Trent Xavier
Trent Xavier

Reputation: 237

How can I change a file change name as it is uploaded with Flask?

I'm trying to create a web app for my team at work and we want it to take user uploaded photos and rename them as they're uploaded. For now, I have a directory on my machine where the files go. My app takes 3 inputs: Name, Email and the file to be uploaded. Upon a user clicking the "upload" button, I want the file to show up in my directory as the email address they entered. For example:

Name: trent
Email: [email protected]
File: photo_of_trent.jpg

I would like the uploaded file to show up in my directory as [email protected].

My Python/Flask code is as follows:

import os
from flask import Flask, render_template
from flask_uploads import UploadSet, configure_uploads, IMAGES, patch_request_class
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileRequired, FileAllowed
from wtforms import StringField
from wtforms import SubmitField
from wtforms.validators import DataRequired, Email

basedir = os.path.abspath(os.path.dirname(__file__))

app = Flask(__name__)
app.config['SECRET_KEY'] = 'I have a dream'
app.config['UPLOADED_PHOTOS_DEST'] = os.path.join(basedir, 'uploads') # you'll need to create a folder named uploads

photos = UploadSet('photos', IMAGES)
configure_uploads(app, photos)
patch_request_class(app)  # set maximum file size, default is 16MB


class UploadForm(FlaskForm):
    name = StringField('Name', [DataRequired()])
    email = StringField('Email', [Email(message='Not a valid email address.'), DataRequired()])
    photo = FileField(validators=[FileAllowed(photos, 'Image only!'), FileRequired('File was empty!')])
    submit = SubmitField('Upload')


@app.route('/', methods=['GET', 'POST'])
def upload_file():
    form = UploadForm()
    if form.validate_on_submit():
        filename = photos.save(form.photo.data)
        file_url = photos.url(filename)
    else:
        file_url = None
    return render_template('index.html', form=form, file_url=file_url)


if __name__ == '__main__':
    app.run()

and my html is as follows:

{% extends 'layout.html' %}

{% block styles %}
    <link rel="stylesheet" href="{{ url_for('static', filename='css/forms.css') }}" rel="stylesheet" type="text/css">
{% endblock %}


{% block content %}
<div class="formwrapper">
  <h2 class="title">Contact</h2>
  <form method="POST" action="/" enctype="multipart/form-data">
      <div class="form-field">{{ form.name.label }} {{ form.name(size=20) }}
      {% if form.name.errors %}
        <ul class="errors">
          {% for error in form.name.errors %}
            <li>{{ error }}</li>
          {% endfor %}
        </ul>
      {% endif %}
      </div>
      <div class="form-field">{{ form.email.label }} {{ form.email }}
      {% if form.email.errors %}
        <ul class="errors">
            {% for error in form.email.errors %}
                <li>{{ error }}</li>
            {% endfor %}
        </ul>
    {% endif %}
      </div>
       {{ form.hidden_tag() }}
     {{ form.photo }}
      {{ form.submit }}

  </form>
</div>
{% endblock %}

It's a not super complex and I kind of mangled this code together as it's my first substantive experience with Flask. There's a little jinja sprinkled in there as well as far as the html is concerned. So far the program only uploads the file with the name of the file. Any help is appreciated. Thank you.

Upvotes: 1

Views: 1799

Answers (1)

djnz
djnz

Reputation: 2050

The UploadSet.save() function takes a parameter name, which should give you what you want.

e.g.

photos.save(form.photo.data, name=f"{form.email.data}.jpg") 

Note: I'm not sure how the file extension will be handled in this case, so you may need to test/tweak this.

Upvotes: 3

Related Questions