Lors de la création d'une application Web, il est pratique d'avoir un modèle. Cette fois, je voudrais vous présenter le modèle de l'application Flask que j'utilise habituellement.
C'est une application web qui crée et gère un simple PRJ avec.
Les principales spécifications du site sont les suivantes.
Comme mentionné ci-dessus, c'est une application simple, c'est donc une échelle qui peut être écrite dans un seul fichier, Je souhaite organiser soigneusement les dossiers pour garantir l'évolutivité et la lisibilité.
En particulier, les dossiers ont été organisés en tenant compte des points suivants.
La structure réelle des dossiers est la suivante.
tree
dossier racine
│ .gitignore
│ LICENSE
│ main.py Le premier serveur d'applications à être exécuté
│ Procfile Utilisé lors de l'exécution sur Heroku
│ README.md
│ requirements.txt Utilisé lors de l'exécution sur Heroku
│
├─.fichier de configuration vscode VSCode (pour gitignore)
│ launch.Définir la configuration de débogage json
│ settings.json Spécification de l'environnement virtuel Python, etc.
│
├─biz Business Logic Storage
│ prj.Écrire une logique métier telle que les opérations py DB et les appels d'API
│
├─mw Middleware (filtre) stockage
│ prj.Écrivez le traitement global de la couche intermédiaire qui relie la route py et le biz
│
├─route Stockage de la définition d'itinéraire
│ prj.Ecrire une définition de routage pour chaque ressource py
│ top.Ecrire une définition de routage pour chaque ressource py
│
├─ Stockage statique de contenu statique
│ ├─common Contenu statique utilisé sur toutes les pages
│ │ ├─css
│ │ │ page.css
│ │ │
│ │ └─js
│ │ page.js
│ │
│ ├─prj Stockage de contenu statique par ressource
│ │ ├─css
│ │ │ page.css
│ │ │
│ │ └─js
│ │ page.js
│ │
│ └─top Stockage de contenu statique par ressource
│ ├─css
│ │ page.css
│ │
│ └─js
│ page.js
│
└─ Modèles Stockage de modèles Jinja
│ footer.Pied de page commun html
│ header.en-tête commun html
│ layout.définition de la mise en page html
│ top.Page individuelle pour chaque ressource html (1 fichier système complet)
│
└─prj Page individuelle par ressource (système multi-pages)
entry.html
search.html
show.html
Lorsque vous démarrez le serveur Flask, exécutez main.py.
Lorsque le serveur Flask accepte une requête de l'utilisateur vers la page TOP, il traite selon le flux suivant. Il n'y a pas de logique particulière dans le traitement lorsque la page TOP est affichée et que le modèle correspondant est simplement renvoyé, de sorte que le flux de traitement est le suivant.
https: // my-site.com /
avec un navigateurroute / top.py
route / top.py
renvoie la méthode render_template ('top')
render_template ('top')
a été renvoyée, utilisez donc template / top.html
pour configurer la page TOP et renvoyer le résultat au navigateur.Le flux de traitement de l'écran PRJ sera expliqué grossièrement en utilisant l'écran détaillé PRJ comme exemple.
Contrairement à l'écran TOP, l'écran PRJ doit implémenter plusieurs actions telles que l'enregistrement, la recherche et la référence. Par conséquent, chaque couche a les rôles suivants.
En concevant de cette manière, le traitement peut être divisé en chaque couche et géré d'une manière facile à comprendre. Cela permet également de voir plus facilement où apporter des corrections lors de l'ajout de nouvelles fonctionnalités.
※たとえば、新しいアクションdeleteを追加したければ、route、mw、biz、templateの各prj.py/prj.htmlにdeleteアクションに対応するメソッドを追加する、など。
Quant à la relation de traitement entre les couches, nous la mettrons en œuvre avec la politique suivante.
Importez * .py dans le dossier d'itinéraire et ʻApp.register_blueprint () `afin que diverses requêtes puissent être acheminées correctement.
main.py
from flask import Flask, redirect, url_for
app = Flask(__name__)
from route.top import top
from route.prj import prj
app.register_blueprint(top)
app.register_blueprint(prj)
if __name__ == '__main__':
app.debug = True
app.run(host='127.0.0.1',port=5000)
route/top.py
Seul le processus pour afficher l'écran TOP.
Parce que c'est le routage lorsque la route du site (https: // mon-site.com /
) est accédée
L'url_prefix de Blueprint définit ''
(caractère vide).
route/top.py
from flask import Flask, render_template, request, Blueprint
top = Blueprint('top', __name__, url_prefix='')
@top.route('/')
def index():
return render_template('top.html', title='TOP')
route/prj.py
définition de routage système prj.
Définissez `` / prj'dans le préfixe url_prefix de Blueprint. En faisant cela, vous serez en mesure d'accepter les demandes de
https: // mon-site.com / prj / ~. En définissant une route comme
@ prj.route ('/ search', methods = ['POST']), diverses actions telles que
https: // mon-site.com / prj / search` sont acceptées. Pourront.
route/prj.py
from flask import Flask, render_template, request, Blueprint
from mw.prj import parse, search_prj, get_prj, create_prj, update_prj
prj = Blueprint('prj', __name__, url_prefix='/prj')
@prj.route('/')
def index():
return render_template('prj/search.html', title='Recherche de projet', prj={})
@prj.route('/search', methods=['POST'])
def search():
q = parse(request)
if q is None:
#Retour anticipé
return jsonify({'code': 'W00100','message': 'La valeur saisie n'est pas valide.'})
#Rechercher DB avec les conditions saisies
data = search_prj(q)
#Afficher les résultats de la recherche
return jsonify({'data': data})
@prj.route('/show/<prj_id>', methods=['GET'])
def show(prj_id):
if prj_id is None:
#Retour anticipé
return render_template('prj/show.html', title='Détails du projet', data={})
# prj_Rechercher DB par identifiant
data = get_prj(prj_id)
#Afficher la page de détails
return render_template('prj/show.html', title='Détails du projet', data=data)
@prj.route('/entry', methods=['GET'])
def entry():
#Affichage initial de l'écran de saisie PRJ
return render_template('prj/entry.html', title='Création de projet')
@prj.route('/create', methods=['POST'])
def create():
#Créer PRJ
data = create_prj(parse(request))
#Afficher la page de détails
return render_template('prj/show.html', title='Détails du projet', data=data, message='J'ai créé un projet.')
mw/prj.py Écrivez un processus de vérification et un processus d'appel Biz pour traiter chaque action.
mw/prj.py
from flask import request
import biz.prj as prj
def parse(request):
#Omis
def search_prj(dto):
#Omis
def get_prj(prj_id):
"""
Obtenez le projet avec l'ID de projet spécifié
"""
return prj.get(prj_id)
def create_prj(dto):
#Omis
def update_prj(data, dto):
#Omis
biz/prj.py Traitement de l'accès à l'API et traitement de l'accès à la base de données. L'exemple ci-dessous décrit un processus get qui appelle une API via HTTP. De plus, étant donné que les points de terminaison d'API et les clés d'API sont des informations confidentielles en tant que système, ils sont définis pour être lus à partir des variables d'environnement.
biz/prj.py
import requests
import os
api_endpoint = os.environ.get('API_ENDPOINT')
headers = {
'x-api-key':os.environ.get('API_KEY')
}
def get(prj_id):
r_get = requests.get(api_endpoint + '/prj/' + prj_id, headers=headers)
return r_get.json()
template/layout.html Modèle pour toutes les pages HTML. CSS et JS communs à toutes les pages peuvent être lus et définis dans ce layout.html. J'essaye de ne pas l'écrire sur chaque page.
{% Block css%}
et {% block js%}
sont définis pour que CSS et JS individuellement pour chaque page puissent être lus.
Le contenu de la balise body est défini comme étant un en-tête commun, le contenu de chaque page et un pied de page commun.
<link rel="stylesheet" href="/static/common/css/page.css" />
<script src="/static/common/js/page.js"></script>
Lors de la lecture de contenu statique sous static, href et src sont définis par une barre oblique comme / static
.
C'est le même layout.html pour le contenu statique commun sous static / common /
même si la hiérarchie des pages est différente comme template / top.html
et template / prj / show.html
. C'est pour qu'il puisse être lu en utilisant.
template/layout.html
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
<meta http-equiv="Content-Type" content="text/html" charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0" />
<!--Style commun-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.8.2/css/bulma.min.css">
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
<link rel="stylesheet" href="/static/common/css/page.css" />
<!--Page individuelle CSS-->
{% block css %}
{% endblock %}
</head>
<body class="has-navbar-fixed-top">
<!--entête-->
{% include "header.html" %}
<!--contenu-->
{% block content %}
{% endblock %}
<!--bas de page-->
{% include "footer.html" %}
<!--JS commun-->
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="/static/common/js/page.js"></script>
<!--Page individuelle JS-->
{% block js %}
{% endblock %}
</body>
</html>
template/top.html
template/top.html
{% extends "layout.html" %}
{% block css %}
<link rel="stylesheet" href="/static/top/css/page.css" type="text/css" />
{% endblock %}
{% block content %}
<section class="hero is-medium is-primary is-bold">
<div class="hero-body">
<div class="container">
<div class="columns is-centered">
<div class="column is-narrow">
<h1 class="title is-1">
Site Concept
</h1>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
{% block js %}
<script async src="/static/top/js/page.js"></script>
{% endblock %}
template/prj/show.html
template/prj/show.html
{% extends "layout.html" %}
{% block css %}
<link rel="stylesheet" href="/static/prj/css/page.css" type="text/css" />
{% endblock %}
{% block content %}
<section class="hero is-medium is-primary is-bold">
<div class="hero-body">
<div class="container">
<div class="columns is-centered">
<div class="column is-narrow">
<h1 class="title is-1">
{{ data['name'] }}
</h1>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
{% block js %}
<script async src="/static/prj/js/page.js"></script>
{% endblock %}
Le code d'application créé à l'aide de ce modèle est publié sur Github. https://github.com/KeitaShiratori/ripple
Recommended Posts