[PYTHON] Comment faire correspondre WTForms TextArea à la suppression de fichier

Contexte

Quand j'ai implémenté un projet avec Flask, Dans le formulaire d'enregistrement de clé publique (zone de texte) qui a conduit à "Copier et coller", Un utilisateur final a déposé le fichier. Je pensais qu'il y avait des gens qui faisaient ça, mais j'ai cherché si je pouvais y arriver ... StackOverflow: Load Textfile via Drag and Drop on Textarea Je l'ai trouvé.

J'ai trouvé que je pouvais faire du JavaScript simple, donc Je l'ai implémenté avec Flask.

Flask Tout d'abord, définissez le formulaire d'enregistrement de clé publique dans Flask comme la classe FORM RegistForm. La validation de la clé publique utilise la bibliothèque sshpubkeys, qui n'est pas le sujet principal.

Il s'agit d'une application de test qui reçoit et affiche uniquement les données vérifiées des données du formulaire.

import os
from flask import (
    Flask,
    request,
    render_template,
    redirect,
    url_for,
)

from flask_wtf import FlaskForm
from wtforms import TextAreaField, SubmitField, ValidationError
from wtforms.validators import InputRequired
from sshpubkeys import SSHKey, InvalidKeyError, MalformedDataError

class RegistForm(FlaskForm):
    pubkey = TextAreaField("PublicKey",validators=[InputRequired()])
    submit = SubmitField("OK")
    reset = SubmitField("RESET")

    def validate_pubkey(self, field):
        if field.data.find('\n') >1:
            raise ValidationError("Too Many Publickey")

        sshpubkey = SSHKey(field.data, strict=True)
        if sshpubkey.key_type != b"ssh-rsa":
            raise ValidationError("Invalid Key Type")

        try:
            sshpubkey.parse()
        except InvalidKeyError as err:
            raise ValidationError("Invalid PublicKey")
        except MalformedDataError as err:
            raise ValidationError("Malformed key Error")
        except NotImplementedError as err:
            raise ValidationError("Undefined Error")


app = Flask(__name__, static_folder='static')
app.config['SECRET_KEY']='12345678901234567890'

@app.route("/", endpoint="register", methods=["GET", "POST"])
def register():
    form = RegistForm()
    if request.method == "GET":
        return render_template("test.html",
                               form=form,
                               endpoint="register")

    if form.validate_on_submit():
        return form.pubkey.data
    else:
        print(f'vaslidation error')
        return redirect(url_for("register"))


if __name__ == "__main__":
    app.run(
        host=os.getenv("APP_HOST", "localhost"),
        port=os.getenv("APP_PORT", 8080),
        debug=True,
    )

JavaScript

Préparez les fonctions suivantes dans static / functions.js.

function dropfile(file) {
    var reader = new FileReader();
    reader.onload = function(e) {
        notepad.value = e.target.result.replace(/(?:\r\n|\r|\n)/g, '');
    };
    reader.readAsText(file, "UTF-8");
};

notepad.ondrop = function(e) {
    e.preventDefault();
    var file = e.dataTransfer.files[0];
    dropfile(file);
};

J'utilise un objet DataTransfer, mais tous les navigateurs ne publient pas l'objet. S'il s'agit d'un navigateur moderne, il ne devrait y avoir aucun problème ...

HTML

En fait, c'est la seule chose qui semble être un talent. L'identifiant d'attribut "notepad" est donné au champ de la classe définie dans forms.py.

{% extends "base.html" %}

{% block contents %}

<form action="{{ url_for( endpoint ) }}" method="post">
{{ form.hidden_tag() }}
{{ form.pubkey(id="notepad", raws=6, cols=80,
               placeholder="Copy&Past or Drag&Drop here!") }}
{{ form.submit }}
{{ form.reset }}
</form>
{% endblock contents %}

rows, cols et placeholder peuvent être attribués à render_kw au format dictionnaire dans la définition de classe, mais je pense qu'il vaut mieux ne pas définir grand-chose lié au dessin dans la classe.

render_kw={"rows": 6, "cols": 80, "placeholder": "Copy&Paste" }

Cela n'a rien à voir non plus avec le sujet principal, mais certaines personnes peuvent s'y intéresser. Pour le moment, préparez un tel base.html.

{% from "_defaults.html" import render_htmlattribs, render_styles, render_scripts %}

{% block doc -%}
<!DOCTYPE html>
<html{% block html_attribs %} {{ render_htmlattribs() }}{% endblock html_attribs %}>
  {%- block html %}
  <head>
    {%- block head %}
    <title>{% block title %}{{ render_title() }}{% endblock title %}</title>

      {%- block metas %}
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta charset="UTF-8">
      {%- endblock metas %}
      {%- block favicon %} {%- endblock favicon %}

      {%- block styles %}
      {{ render_styles() }}
      {%- endblock styles %}

    {%- endblock head %}
  </head>
  <body{% block body_attribs %}{% endblock body_attribs %}>
    {%- block body %}

    {% block contents %} {% endblock contents %}

    {% block footer %}
      {{ render_footer() }}
    {%- endblock footer %}

    {% block scripts %}
      {{ render_scripts() }}
    {%- endblock scripts %}

    {%- endblock body %}
  </body>
  {%- endblock html %}
</html>
{% endblock doc -%}

La macro définie dans _defaults.html ressemble à ceci: Je l'utilise tout le temps, alors j'essaye de charger bootstrap et jquery. Vous n'êtes pas obligé d'avoir ça. Tout ce que vous avez à faire est de charger static / functions.js.

{% macro render_htmlattribs() -%}
lang="ja"
{%- endmacro %}

{% macro render_styles() %}
    <link href="/static/bootstrap-4.5.2/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/base.css" rel="stylesheet">
{% endmacro %}


{% macro render_scripts() %}
    <script src="/static/jquery-3.5.1.min.js"></script>
    <script src="/static/bootstrap-4.5.2/js/bootstrap.min.js"></script>
    <script src="/static/functions.js"></script>
{% endmacro %}

Matériel de référence

Recommended Posts

Comment faire correspondre WTForms TextArea à la suppression de fichier
Comment faire une traduction japonais-anglais
Comment créer un bot slack
Comment créer un robot - Avancé
Comment créer une fonction récursive
[Blender] Comment créer un plug-in Blender
[Blender] Comment rendre les scripts Blender multilingues
Comment créer un robot - Basic
Comment créer un fichier de configuration
Comment faire une commande pour lire le fichier de paramètres avec pyramide
Comment rendre les caractères de Word Cloud monochromatiques
[Python] Comment convertir un fichier db en csv
Comment rendre le sélénium aussi léger que possible
[Python] Comment rendre une classe itérable
Comment convertir Python en fichier exe
[Cocos2d-x] Comment créer une liaison de script (partie 2)
Comment créer une clé USB à démarrage multiple (compatible Windows 10)
Comment créer un indicateur personnalisé Backtrader
Comment créer un plan de site Pelican
[Cocos2d-x] Comment créer une liaison de script (partie 1)
Comment déposer Google Docs dans un dossier dans un fichier .txt avec python
LINUX: Comment faire correspondre les touches fléchées à 2,4,6,8 sur des notes sans dix touches
Comment créer un système de dialogue dédié aux débutants
Comment lire un fichier CSV avec Python 2/3
Comment déguiser un fichier ZIP en fichier PNG
Comment créer un pilote de périphérique Linux intégré (8)
Comment créer un plug-in Spigot (pour les débutants Java)
Comment créer un pilote de périphérique Linux intégré (1)
Comment créer un pilote de périphérique Linux intégré (4)
Comment rendre plusieurs noyaux sélectionnables sur Jupyter
Comment créer un fichier JSON en Python
Comment créer un dictionnaire avec une structure hiérarchique.
Comment créer un pilote de périphérique Linux intégré (7)
[Python] Comment lire des fichiers Excel avec des pandas
Comment créer un pilote de périphérique Linux intégré (2)
Comment créer une sortie JSON Scintillante en japonais
Comment créer un pilote de périphérique Linux intégré (3)
Comment créer un plug-in QGIS (génération de package)
J'ai lu "Comment créer un laboratoire de piratage"
Comment créer un pilote de périphérique Linux intégré (6)
Comment créer le plugin Python de Substance Painter (Introduction)
Comment créer un pilote de périphérique Linux intégré (5)
Comment créer un pilote de périphérique Linux intégré (10)
Comment rendre le Python des débutants plus rapide [numpy]
Comment lire des fichiers dans différents répertoires
Comment apporter des modifications à l'interpréteur Python dans Pycharm
Comment créer un pilote de périphérique Linux intégré (9)
Inspiré par "Comment créer du JavaScript purement fonctionnel"
Comment faire pour qu'AWS rekognition reconnaisse les fichiers image locaux
[Suite] Inspiré par "Comment créer du JavaScript purement fonctionnel"
Comment faire reconnaître Yubico Yubikey par Manjaro Linux
Expliquez en détail comment créer un son avec python
Comment faire un jeu de tir avec toio (partie 1)
Backtrader Comment importer un indicateur depuis un autre fichier
Comment mesurer le temps de lecture d'un fichier mp3 avec python
Comment faire un test unitaire Part.2 Conception de classe pour les tests
Comment convertir un fichier JSON en fichier CSV avec Python Pandas