AttributeError: объект «NoneType» не имеет атрибута «имя файла» для загрузки Flask

Я использую Колба 1.0.2 и Колба-WTF 0.14.2, но не понимаю, почему имя файла пустое.

Сначала я создаю такие формы.py

images = UploadSet('images', IMAGES)
docs = UploadSet('docs', ['pdf', 'doc', 'docx', 'PDF', 'DOC', 'DOCX', 'jpg', 'jpeg', 'png', 'JPG', 'PNG', 'JPEG'])
configure_uploads(app, (images, docs))
class EvenementForm(FlaskForm):
    titre = StringField(u'titre', validators=[DataRequired()])
    periode = StringField(u'periode', validators=[DataRequired()])
    description = TextAreaField(u'description', validators=[DataRequired()])
    lieu = StringField(u'lieu', validators=[DataRequired()])
    image = FileField(u'image', validators=[FileAllowed(docs, u'Documents seulement. Le poids ne doit pas dépasser les 300 Ko!')])

    def __init__(self, *args, **kwargs):
        super(EvenementForm, self).__init__(*args, **kwargs) 

Тогда мой views.py выглядит так

@admin.route('/events', methods=['GET', 'POST'])
def events():
     form = EvenementForm()
     if request.method == 'POST' and form.validate_on_submit():
          evenement = Evenements(titre=form.titre.data, lieu=form.lieu.data, periode=form.periode.data, description=form.description.data)

          otherfile = form.image.data.filename

          if otherfile:
               otherfile = secure_filename(otherfile)
               date = "{:%I%M%S%f%d%m%Y}".format(datetime.now())
               otherfile = date + otherfile
               form.image.data.save(os.path.join(app.config['UPLOAD_FOLDER'], 'resumes/'+otherfile))
               evenement.image = otherfile
          db.session.add(evenement)
          db.session.commit()
          flash('Thanks for adding')
          return redirect(url_for('admin.events'))
     return render_template("admin/events.html", form=form)

и мой шаблон выглядит так:

<form action = "" method = "POST" enctype = "multipart/form-data">
    <div class = "col-lg-12">
        {{ form.csrf_token }}
        <input type = "hidden" class = "form-control" name = "event_id" value = "0" autocomplete = "off">
        <div class = "form-group">
            <label for = "speaker_name">Titre :</label>
            {{ form.titre(placeholder='Entrez le titre de l\'évenement', class='form-control', required='required') }}
            <span style = "color:red">{% if form.titre.errors %}{{ form.titre.errors[0] }}{% endif %}</span>
        </div>
        <div class = "form-group">
            <label for = "speaker_job">Lieu:</label>
            {{ form.lieu(placeholder='Entrez le lieu de l\'évenement', class='form-control', required='required') }}
            <span style = "color:red">{% if form.lieu.errors %}{{ form.lieu.errors[0] }}{% endif %}</span>
        </div>
        <div class = "form-group">
            <label for = "speaker_job">Lieu:</label>
            {{ form.periode(placeholder='Entrez la periode de l\'évenement', class='form-control', required='required') }}
            <span style = "color:red">{% if form.periode.errors %}{{ form.periode.errors[0] }}{% endif %}</span>
        </div>
        <div class = "form-group">
            <label for = "speaker_job">Lieu:</label>
            {{ form.description(placeholder='Entrez la description de l\'évenement', class='textarea textarea-style', required='required') }}
            <span style = "color:red">{% if form.description.errors %}{{ form.description.errors[0] }}{% endif %}</span>     
        </div>
        <div class = "form-group">
            <label for = "speaker_picture">Image</label>
            {{ form.image(placeholder='Entrez l\'image de l\'évenement', class='form-control', required='required') }}
            <span style = "color:red">{% if form.image.errors %}{{ form.image.errors[0] }}{% endif %}</span>
        </div> 
        <button type = "button"  class = "btn btn-bold btn-pure btn-danger" data-dismiss = "modal">
            Annuler
        </button>
        <button type = "submit" class = "btn btn-bold btn-pure btn-info float-right">
            Enregistrer
        </button>
    </div>
</form>

И я сталкиваюсь с этой ошибкой

AttributeError: 'NoneType' object has no attribute 'filename'

как я мог это решить?

Новые приложения с использованием ChatGPT
Новые приложения с использованием ChatGPT
Я собираюсь вернуться к теме, которую уже освещал ранее, - чатгпт.
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Другой маршрут в Flask Python
Другой маршрут в Flask Python
Flask - это фреймворк, который поддерживает веб-приложения. В этой статье я покажу, как мы можем использовать @app .route в flask, чтобы иметь другую...
2
0
3 826
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Проблема в том, что form.image.data.filename, когда пользователь не предоставляет файл, filename не будет, потому что form.image.data будет иметь None в качестве значения

Вам нужно проверить form.image.data себя, а не filename

Это выглядит так:

otherfile = form.image.data
if otherfile:
    # I see your assigning filename to this variable,
    # Next line does the same, I don't recommend it this way
    otherfile = otherfile.filename
    # Do other stuff

В документации WTForms есть пример использования

Также вы можете использовать валидатор FileRequired в определении класса вашей формы, чтобы убедиться, что файл всегда есть, иначе данные не будут действительными.

image = FileField(u'image', validators=[FileAllowed(docs, u'Documents seulement. Le poids ne doit pas d&eacute;passer les 300 Ko!'), FileRequired()])

Просто добавьте тип шифрования в тег формы, как это

<form class = "col s12"method='POST' enctype = "multipart/form-data">

Другие вопросы по теме