Передача проверок Flask WTForms в Bootstrap Alerts через Flask-Bootstrap - PullRequest
0 голосов
/ 18 сентября 2018

новый пользователь Flask здесь ... Я создаю красивую кнопку загрузки файла для своего приложения колбы.Кнопка по существу использует WTForms для проверки того, что могут быть загружены только файлы CSV и TXT.Загрузка работает, но как я могу передать ошибки проверки на экран в качестве предупреждения при загрузке?Например:

  1. нажатие кнопки загрузки приведет к появлению предупреждения «файл не выбран»
  2. нажатие кнопки «Загрузить файл с jpeg» приведет к «неправильному формату файла»

любые предложения будут оценены!

Мои forms.py:

class UploadForm(FlaskForm):
    validators = [FileRequired(message='There was no file!'),
                  FileAllowed(['csv', 'txt'], message='Must be a csv file!')]

    input_file = FileField('', validators=validators)
    submit = SubmitField(label="Upload")

мой route.py:

@app.route('/upload', methods=['GET', 'POST'])
def upload():

    form = UploadForm()

    if request.method == 'POST' and form.validate_on_submit():
        input_file = request.files['input_file']

        # Do stuff
        filename = secure_filename(input_file.filename)

        # save file to disk to some folder defined in a separate config file....
        data = os.path.join(SOME_UPLOAD_FOLDER, filename)
        input_file.save(data)

        return redirect(url_for('upload'))

else:
    return render_template('upload.html', form=form)

и, наконец, HTML / CSS / JS:

{% extends "bootstrap/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block html_attribs %} lang="en" charset="utf-8"{% endblock %}

{% block metas %}
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
{% endblock %}


{% block styles %}

    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <style>
        #browsebutton {
            background-color: white;
        }

        #my-file-selector {
            display: none;
        }
    </style>


{% endblock %}

{% block content %}

    <div class="container">
        <div class="jumbotron">
            <h3>File Uploader Example</h3>


            <div class="row">
                <form class="form-inline center-block" action="/upload" method="POST" enctype="multipart/form-data">
                    {{ form.hidden_tag() }}
                    <div class="input-group">
                        <label id="browsebutton" class="btn btn-default input-group-addon" for="my-file-selector">
                            {{ form.input_file(id="my-file-selector") }}
                            Browse...
                        </label>
                        <input type="text" class="form-control" readonly>
                    </div>
                    {{ form.submit(class_="btn btn-primary") }}
                </form>
            </div>
        </div>
    </div>

{% endblock %}


{% block scripts %}

    <! -- jquery -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
            integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

    <!-- pretty upload button -->
    <script>
    $(function() {

      // We can attach the `fileselect` event to all file inputs on the page
      $(document).on('change', ':file', function() {
        var input = $(this),
            numFiles = input.get(0).files ? input.get(0).files.length : 1,
            label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
        input.trigger('fileselect', [numFiles, label]);
      });

      // We can watch for our custom `fileselect` event like this
      $(document).ready( function() {
          $(':file').on('fileselect', function(event, numFiles, label) {

              var input = $(this).parents('.input-group').find(':text'),
                  log = numFiles > 1 ? numFiles + ' files selected' : label;

              if( input.length ) {
                  input.val(log);
              } else {
                  if( log ) alert(log);
              }

          });
      });

    });
    </script>

{% endblock %}

1 Ответ

0 голосов
/ 19 сентября 2018

Если вы используете WTForms, я бы порекомендовал использовать макросы для визуализации полей формы.Подробно здесь , и вы можете получить пример там (вы можете найти некоторые другие онлайн, которые помогут вам настроить, а не писать с нуля).

Обратите внимание, что в документации WTForm макрос render_field() проверяет наличие ошибок в вашем поле:

{% if field.errors %}
  <ul class=errors>
  {% for error in field.errors %}
    <li>{{ error }}</li>
  {% endfor %}
  </ul>
{% endif %}

Конечно, вы можете решить не использовать макросы, в этом случае вы можете просто использовать приведенный выше фрагмент непосредственнов вашей HTML-форме с form.input_file.errors вместо field.errors

...