Tout d'abord [modèle HTML](https://sbcr-dl-and-idea.s3-ap-northeast-1.amazonaws.com/2019-03-16-98892-HTML+%26+CSS%E3%81 % A8Web% E3% 83% 87% E3% 82% B6% E3% 82% A4% E3% 83% B3% E5% 85% A5% E9% 96% 80% E8% AC% 9B% E5% BA% A7 Basé sur /HTML-CSS-Webdesign-2.zip), j'ai créé un fichier html / css pour le site réservé aux cafés et effectué le traitement du routage à l'aide de Flask of Python afin qu'il soit accessible à partir de l'URL. (Comme il s'agit d'un article d'explication de Flask, je n'expliquerai pas comment créer le fichier HTML d'origine ici.)
app.py
flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html', id="home")
@app.route('/menu')
def menu():
return render_template('menu.html', id="menu")
@app.route('/news')
def news():
return render_template('news.html', id="news")
@app.route('/contact')
def contact():
return render_template('contact.html', id="contact")
if __name__ == '__main__':
app.debug = True
app.run()
À cette époque, j'avais peu d'expérience en programmation et j'avais très peu d'expérience avec Python, sans parler de Flask, j'ai donc essayé de traiter facilement les formulaires d'entrée et les formulaires de sortie pour la pratique.
app.py
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html', id="home")
@app.route('/menu')
def menu():
return render_template('menu.html', id="menu")
@app.route('/news')
def news():
return render_template('news.html', id="news")
@app.route('/contact')
def contact():
return render_template('contact.html', id="contact")
@app.route('/review', methods=['GET'])
def review():
return render_template('review.html', id="review")
@app.route('/review', methods=['POST'])
def view_board():
if request.form['username'] and request.form['star'] and request.form['review']:
return render_template('review.html', username=request.form['username'], star=request.form['star'], review=request.form['review'])
if __name__ == '__main__':
app.debug = True
app.run()
review.html
{% extends "theme.html" %}
{% block title %}Coffee House{% endblock %}
{% block head %}
{{ super() }}
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
{% endblock %}
{% block content %}
<div class="form-content wrapper">
<h2 class="page-title">Review</h2>
<form method="POST" action="/review">
<div>
<label for="name">Nom</label>
<input placeholder="Nom" name="username" type="text"/>
</div>
<div class="star-rating">
<div class="star-rating__wrap">
<input class="star-rating__input" id="star-rating-5" type="radio" name="star" value="5">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-5" title="5 out of 5 stars"></label>
<input class="star-rating__input" id="star-rating-4" type="radio" name="star" value="4">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-4" title="4 out of 5 stars"></label>
<input class="star-rating__input" id="star-rating-3" type="radio" name="star" value="3">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-3" title="3 out of 5 stars"></label>
<input class="star-rating__input" id="star-rating-2" type="radio" name="star" value="2">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-2" title="2 out of 5 stars"></label>
<input class="star-rating__input" id="star-rating-1" type="radio" name="star" value="1">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-1" title="1 out of 5 stars"></label>
</div>
</div>
<div>
<label for="message">message</label>
<textarea id="message" placeholder="La revue" name="review"></textarea>
</div>
<input type="submit" class="button" value="Envoyer">
</form>
</div>
{% endblock %}
{% block content2 %}
<div class="wrapper board">
<p>name : {{username}}</p>
{% if star == '1' %}
<p>rating : <img src="/static/images/star.png " width="15" height="15"></p>
{% endif %}
{% if star == '2' %}
<p>rating : <img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"></p>
{% endif %}
{% if star == '3' %}
<p>rating : <img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"></p>
{% endif %}
{% if star == '4' %}
<p>rating : <img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"></p>
{% endif %}
{% if star == '5' %}
<p>rating : <img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"></p>
{% endif %}
<p>message : {{review}}</p>
</div>
{% endblock %}
{% block footer %}
<footer>
<div class="wrapper">
<p><small>© Coffee House</small></p>
</div>
</footer>
{% endblock %}
J'avais affaire à ** jinja2 ** pour la première fois ici, mais j'ai essayé d'utiliser la syntaxe de la boucle lors du traitement de la sortie de classement par étoiles, mais cela n'a pas fonctionné, j'ai donc utilisé l'instruction ** if-else **. Le traitement de sortie du classement par étoiles est décrit. (L'entrée vedette était * font-awesome * et la sortie était un * fichier png *.)
Dans le traitement de diverses fonctions, il est préférable de séparer les fichiers pour chaque fonction car il y a des avantages tels que la lisibilité, la lisibilité et la facilité de mise à jour, j'ai donc décidé de considérer d'abord la structure des fichiers.
Créez un dossier cafe_site dans le répertoire racine et créez-y un fichier ** __ init__.py **
python:./cafe_site/__init__.py
from flask import Flask
app=Flask(__name__)
import cafe_site.views
Ensuite, créez un dossier views dans le dossier cafe_site et enregistrez le script qui génère le site cafe que vous avez créé précédemment en tant que fichier views.py.
python:./cafe_site/views.py
from flask import request, redirect, url_for, render_template, flash, session
from cafe_site import app
@app.route('/')
def index():
return render_template('cafe_site/index.html', id="home")
@app.route('/menu')
def menu():
return render_template('cafe_site/menu.html', id="menu")
@app.route('/news')
def news():
return render_template('cafe_site/news.html', id="news")
@app.route('/contact')
def contact():
return render_template('cafe_site/contact.html', id="contact")
@app.route('/review', methods=['GET'])
def review():
return render_template('review.html', id="review")
@app.route('/review', methods=['POST'])
def view_board():
if request.form['username'] and request.form['star'] and request.form['review']:
return render_template('review.html', username=request.form['username'], star=request.form['star'], review=request.form['review'])
Enfin, créez le fichier de démarrage server.py «directement sous le répertoire racine.
python:./server.py
from cafe_site import app
if __name__ == '__main__':
app.run(debug=True)
Vous pouvez maintenant démarrer l'application flask pour le moment.
Le fichier config.py est un fichier qui décrit les informations d'environnement et les informations de configuration de l'application.
python:./cafe_site/config.py
DEBUG = True
Dans cette application, le mode débogage est activé en tant qu'informations de configuration. (Supprimez'debug = True 'répertorié dans server.py.)
Déclarez de traiter le contenu de config.py comme config dans le fichier init.py pour activer le fichier de configuration.
python:./__init__.py
app.config.from_object('cafe_site.config')
Ici, je voudrais diviser Flask en trois parties, modèle, modèle et vue, et traiter chaque fonction.
Template Placez le dossier de modèles sous le dossier cafe_site et organisez les fichiers HTML à afficher pour l'utilisateur.
html:./cafe_site/templates/theme.html
<!DOCTYPE html>
<html lang="ja">
<head>
{% block head %}
<meta charset="utf-8">
<title>{% block title %}{% endblock %}</title>
<meta name="description" content="Café offrant un espace de travail">
<link rel="icon" type="image/png" href="/static/images/favicon.png ">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSS -->
<link rel="stylesheet" href="https://unpkg.com/ress/dist/ress.min.css">
<link href="https://fonts.googleapis.com/css?family=Philosopher" rel="stylesheet">
<link href="/static/style.css" rel="stylesheet">
{% endblock %}
</head>
<body>
<div id="{{ id }}" class="big-bg">
<header class="page-header wrapper">
<h1><a href="/"><img class="logo" src="/static/images/logo.svg" alt="Café Maison"></a></h1>
<nav>
<ul class="main-nav">
<li><a href="/news">News</a></li>
<li><a href="/menu">Menu</a></li>
<li><a href="/contact">Contact</a></li>
<li><a href="/review">Review</a></li>
</ul>
</nav>
</header>
{% block content %}
{% endblock %}
</div>
{% block content2 %}
{% endblock %}
{% block footer %}
{% endblock %}
</body>
</html>
html:./cafe_site/templates/index.html
{% extends "theme.html" %}
{% block title %}Coffee House{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block content %}
<div class="home-content wrapper">
<h2 class="page-title">We Make Your Relax Space </h2>
<p>Pourquoi n'utilisez-vous pas un café calme dans l'espace pour travailler et étudier? Nous fournissons un espace de détente.</p>
<a class="button" href="/menu">Afficher le menu</a>
</div><!-- /.home-content -->
{% endblock %}
html:./cafe_site/templates/menu.html
{% extends "theme.html" %}
{% block title %}Coffee House{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block content %}
<div class="menu-content wrapper">
<h2 class="page-title">Menu</h2>
<p>
Coffee House propose un régime méditerranéen qui vous aidera à vous concentrer. Il propose un menu qui utilise des ingrédients de fruits de mer.
Des grains de moka soigneusement sélectionnés sont utilisés pour le café mélangé. Vous pourrez mieux travailler et étudier avec une cuisine méditerranéenne, un délicieux café et un espace calme.
</p>
</div><!-- /.menu-content -->
{% endblock %}
{% block content2 %}
<div class="wrapper grid">
<div class="item">
<img src="/static/images/menu1.jpg " alt="">
<p>Service à café</p>
</div>
<div class="item">
<img src="/static/images/menu2.jpg " alt="">
<p>café latté</p>
</div>
<div class="item">
<img src="/static/images/menu3.jpg " alt="">
<p>crêpe</p>
</div>
<div class="item">
<img src="/static/images/menu4.jpg " alt="">
<p>soupe</p>
</div>
<div class="item">
<img src="/static/images/menu5.jpg " alt="">
<p>salade</p>
</div>
<div class="item">
<img src="/static/images/menu6.jpg " alt="">
<p>huître</p>
</div>
<div class="item">
<img src="/static/images/menu7.jpg " alt="">
<p>Tom yam kung</p>
</div>
<div class="item">
<img src="/static/images/menu8.jpg " alt="">
<p>Pâtes aux fruits de mer</p>
</div>
<div class="item">
<img src="/static/images/menu9.jpg " alt="">
<p>Gâteau aux framboises</p>
</div>
</div><!-- /.grid -->
{% endblock %}
{% block footer %}
<footer>
<div class="wrapper">
<p><small>© Coffee House</small></p>
</div>
</footer>
{% endblock %}
html:./cafe_site/templates/news.html
{% extends "theme.html" %}
{% block title %}Coffee House{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block content %}
<div class="wrapper">
<h2 class="page-title">News</h2>
</div><!-- /.wrapper -->
{% endblock %}
{% block content2 %}
<div class="news-contents wrapper">
<article>
<header class="post-info">
<h2 class="post-title">L'intérieur du magasin a été renouvelé.</h2>
<p class="post-date">1/1 <span>2020</span></p>
<p class="post-cat">Catégorie: Présentation de la boutique</p>
</header>
<img src="/static/images/wall.jpg " alt="À l'intérieur du magasin">
<p>
J'ai un peu changé l'intérieur du magasin.
</p>
<p>
L'espace est plus rafraîchissant qu'avant.
</p>
<p>WCB CAFE offrant une cuisine méditerranéenne et du café mélangé.</p>
</article>
<aside>
<h3 class="sub-title">Catégorie</h3>
<ul class="sub-menu">
<li><a href="#">Présentation de la boutique</a></li>
<li><a href="#">Menu à durée limitée</a></li>
<li><a href="#">un événement</a></li>
<li><a href="#">Conversation avec les clients</a></li>
</ul>
<h3 class="sub-title">À propos de cette boutique</h3>
<p>
Souhaitez-vous utiliser un espace de détente pour travailler ou étudier?
Nous le fournissons.
</p>
</aside>
</div><!-- /.news-contents -->
{% endblock %}
{% block footer %}
<footer>
<div class="wrapper">
<p><small>© Coffee House</small></p>
</div>
</footer>
{% endblock %}
html:./cafe_site/templates/contact.html
{% extends "theme.html" %}
{% block title %}Coffee House{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block content %}
<div class="wrapper">
<h2 class="page-title">Contact</h2>
<form action="#">
<div>
<label for="message">message</label>
<textarea id="message" name="your-message"></textarea>
</div>
<input type="submit" class="button" value="Envoyer">
</form>
</div><!-- /.wrapper -->
{% endblock %}
{% block content2 %}
<section id="location">
<div class="wrapper">
<div class="location-info">
<h3 class="sub-title">Café Naha</h3>
<p>
Adresse: ville de Naha, préfecture d'Okinawa<br>
〇〇〇〇〇〇〇 900-0000<br>
〇〇〇〇<br>
Téléphone: 11-1111-1111<br>
Heures d'ouverture: 13:00〜20:00<br>
Jours fériés: mercredi
</p>
</div><!-- /.location-info -->
<div class="location-map">
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d1789.7269103206745!2d127.6771741081368!3d26.21443990219555!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x34e5699c49922617%3A0xda1a9bb8fcac1213!2z44CSOTAwLTAwMTUg5rKW57iE55yM6YKj6KaH5biC5LmF6IyC5Zyw77yR5LiB55uu!5e0!3m2!1sja!2sjp!4v1585272464198!5m2!1sja!2sjp" width="800" height="400" frameborder="0" style="border:0;" allowfullscreen="" aria-hidden="false" tabindex="0"></iframe>
</div><!-- /.location-map -->
</div><!-- /.wrapper -->
</section><!-- /#location -->
<section id="sns">
<div class="wrapper">
<div class="sns-box">
<h3 class="sub-title">Facebook</h3>
<iframe src="https://www.facebook.com/plugins/page.php?href=https%3A%2F%2Fwww.facebook.com%2Ffacebook&tabs=timeline&width=340&height=315&small_header=false&adapt_container_width=true&hide_cover=false&show_facepile=false&appId" width="340" height="315" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowTransparency="true" allow="encrypted-media"></iframe>
</div>
<div class="sns-box">
<h3 class="sub-title">Twitter</h3>
<a class="twitter-timeline" data-height="315" href="https://twitter.com/CoffeeH95724918?ref_src=twsrc%5Etfw">Tweets by CoffeeH95724918</a> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
<div class="sns-box">
<h3 class="sub-title">Youtube</h3>
<iframe width="560" height="315" src="https://www.youtube.com/embed/VDoTkxg9Rac" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div><!-- /.wrapper -->
</section><!-- /#sns -->
{% endblock %}
{% block footer %}
<footer>
<div class="wrapper">
<p><small>© Coffee House</small></p>
</div>
</footer>
{% endblock %}
review.html
{% extends "theme.html" %}
{% block title %}Coffee House{% endblock %}
{% block head %}
{{ super() }}
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
{% endblock %}
{% block content %}
<div class="form-content wrapper">
<h2 class="page-title">Review</h2>
<form method="POST" action="/review">
<div>
<label for="name">Nom</label>
<input placeholder="Nom" name="username" type="text"/>
</div>
<div class="star-rating">
<div class="star-rating__wrap">
<input class="star-rating__input" id="star-rating-5" type="radio" name="star" value="5">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-5" title="5 out of 5 stars"></label>
<input class="star-rating__input" id="star-rating-4" type="radio" name="star" value="4">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-4" title="4 out of 5 stars"></label>
<input class="star-rating__input" id="star-rating-3" type="radio" name="star" value="3">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-3" title="3 out of 5 stars"></label>
<input class="star-rating__input" id="star-rating-2" type="radio" name="star" value="2">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-2" title="2 out of 5 stars"></label>
<input class="star-rating__input" id="star-rating-1" type="radio" name="star" value="1">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-1" title="1 out of 5 stars"></label>
</div>
</div>
<div>
<label for="message">message</label>
<textarea id="message" placeholder="La revue" name="review"></textarea>
</div>
<input type="submit" class="button" value="Envoyer">
</form>
</div>
{% endblock %}
{% block content2 %}
<div class="wrapper board">
<p>name : {{username}}</p>
{% if star == '1' %}
<p>rating : <img src="/static/images/star.png " width="15" height="15"></p>
{% endif %}
{% if star == '2' %}
<p>rating : <img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"></p>
{% endif %}
{% if star == '3' %}
<p>rating : <img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"></p>
{% endif %}
{% if star == '4' %}
<p>rating : <img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"></p>
{% endif %}
{% if star == '5' %}
<p>rating : <img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"><img src="/static/images/star.png " width="15" height="15"></p>
{% endif %}
<p>message : {{review}}</p>
</div>
{% endblock %}
{% block footer %}
<footer>
<div class="wrapper">
<p><small>© Coffee House</small></p>
</div>
</footer>
{% endblock %}
css:./cafe_site/static/style.css
@charset "UTF-8";
/* ********************
partie commune
******************** */
html {
font-size: 100%;
}
body{
font-family: "Yu Gothic Medium", "Yu gothique moyen", YuGothic, "Yu gothique", "Hiragino Kakugo Pro W3", sans-serif;
line-height: 1.7;
color: rgb(0, 0, 0);
}
a {
text-decoration: none;
}
img {
max-width: 100%;
}
.wrapper {
max-width: 1100px;
margin: 0 auto;
padding: 0 4%;
}
/*image de fond*/
.big-bg {
background-size: cover;
background-position: center top;
background-repeat: no-repeat;
}
/*Titre*/
.page-title {
font-size: 5rem;
font-family: 'Philosopher', serif;
text-transform: uppercase;
font-weight: normal;
}
.sub-title {
font-size: 1.375rem;
padding: 0 8px 8px;
border-bottom: 2px #0bd solid;
font-weight: normal;
}
/*bouton*/
.button {
font-size: 1.375rem;
background: #0bd;
color: #fff;
border-radius: 5px;
padding: 18px 32px;
}
.button:hover {
background: #0090aa;
}
/* iframe */
iframe {
width: 100%;
}
/* ********************
HEADER
******************** */
.page-header {
display: flex;
justify-content: space-between;
}
.logo {
width: 210px;
margin-top: 14px;
}
.main-nav {
display: flex;
font-size: 1.25rem;
text-transform: uppercase;
margin-top: 34px;
list-style: none;
}
.main-nav li {
margin-left: 36px;
}
.main-nav a {
color: rgb(0, 0, 0);
}
.main-nav a:hover {
color: #0bd;
}
/* ********************
HOME
******************** */
#home {
background-image: url(./images/main-bg.jpg);
min-height: 100vh;
}
#home .page-title {
text-transform: none;
}
.home-content {
text-align: center;
margin-top: 10%;
}
.home-content p {
font-size: 1.125rem;
margin: 10px 0 42px;
}
/* ********************
NEWS
******************** */
#news {
background-image: url(./images/news-bg.jpg);
height: 270px;
margin-bottom: 40px;
}
#news .page-title {
text-align: center;
}
.news-contents {
display: flex;
justify-content: space-between;
margin-bottom: 50px;
}
/* ********************
Partie article
******************** */
article {
width: 74%;
}
.post-info {
position: relative;
padding-top: 4px;
margin-bottom: 40px;
}
.post-date {
background: #0bd;
border-radius: 50%;
color: #fff;
width: 100px;
height: 100px;
font-size: 1.625rem;
text-align: center;
position: absolute;
top: 0;
padding-top: 10px;
}
.post-date span {
font-size: 1rem;
border-top: 1px rgba(255,255,255,.5) solid;
padding-top: 6px;
display: block;
width: 60%;
margin: 0 auto;
}
.post-title {
font-family: "Yu Mincho", "YuMincho", serif;
font-size: 2rem;
font-weight: normal;
}
.post-title,
.post-cat {
margin-left: 120px;
}
article img {
margin-bottom: 20px;
}
article p {
margin-bottom: 1rem;
}
/*Barre latérale*/
aside {
width: 22%;
}
.sub-menu {
margin-bottom: 60px;
list-style: none;
}
.sub-menu li {
border-bottom: 1px #ddd solid;
}
.sub-menu a {
color: rgb(0, 0, 0);
padding: 10px;
display: block;
}
.sub-menu a:hover {
color: #0bd;
}
aside p {
padding: 12px 10px;
}
/* ********************
MENU
******************** */
#menu {
background-image: url(./images/menu-bg.jpg);
min-height: 100vh;
}
.menu-content {
max-width: 560px;
margin-top: 10%;
}
.menu-content .page-title {
text-align: center;
}
.menu-content p {
font-size: 1.125rem;
margin: 10px 0 0;
}
.grid {
display: grid;
gap: 26px;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
margin-top: 6%;
margin-bottom: 50px;
}
/* ********************
CONTACT
******************** */
#contact {
background-image: url(./images/contact-bg.jpg);
min-height: 100vh;
}
/*Forme*/
form div {
margin-bottom: 14px;
}
label {
font-size: 1.125rem;
margin-bottom: 10px;
display: block;
}
input[type="text"],
input[type="email"],
textarea {
background: rgba(255,255,255,.5);
border: 1px #fff solid;
border-radius: 5px;
padding: 10px;
font-size: 1rem;
}
input[type="text"],
input[type="email"] {
width: 100%;
max-width: 240px;
}
textarea {
width: 100%;
max-width: 480px;
height: 6rem;
}
input[type="submit"] {
border: none;
cursor: pointer;
line-height: 1;
}
/*Informations sur le magasin / carte*/
#location {
padding: 4% 0;
}
#location .wrapper {
display: flex;
justify-content: space-between;
}
.location-info {
width: 22%;
}
.location-info p {
padding: 12px 10px;
}
.location-map {
width: 74%;
}
/* SNS */
#sns {
background: #FAF7F0;
padding: 4% 0;
}
#sns .wrapper {
display: flex;
justify-content: space-between;
}
#sns .sub-title {
margin-bottom: 30px;
}
.sns-box {
width: 30%;
}
/* ********************
review
******************** */
#review {
background-image: url(./images/review-bg.jpg);
min-height: 100vh;
}
.form-content {
max-width: 560px;
margin-top: 10%;
}
.form-content .page-title {
text-align: center;
}
form div {
margin-bottom: 14px;
}
label {
font-size: 1.125rem;
margin-bottom: 10px;
display: block;
}
input[type="text"],
textarea {
background: rgba(255,255,255,.5);
border: 1px #fff solid;
border-radius: 5px;
padding: 10px;
font-size: 1rem;
}
input[type="text"] {
width: 100%;
max-width: 240px;
}
textarea {
width: 100%;
max-width: 480px;
height: 6rem;
}
input[type="submit"] {
border: none;
cursor: pointer;
line-height: 1;
}
.star-rating{
font-size: 0;
}
.star-rating__wrap{
display: inline-block;
font-size: 1rem;
}
.star-rating__wrap:after{
content: "";
display: table;
clear: both;
}
.star-rating__ico{
float: right;
padding-left: 2px;
cursor: pointer;
color: #FFB300;
}
.star-rating__ico:last-child{
padding-left: 0;
}
.star-rating__input{
display: none;
}
.star-rating__ico:hover:before,
.star-rating__ico:hover ~ .star-rating__ico:before,
.star-rating__input:checked ~ .star-rating__ico:before
{
content: "\f005";
}
.board {
display: grid;
gap: 26px;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
margin-top: 6%;
margin-bottom: 50px;
}
/* ********************
bas de page
******************** */
footer {
background: rgb(0, 0, 0);
text-align: center;
padding: 26px 0;
}
footer p {
color: #fff;
font-size: 0.875rem;
}
/* ********************
version mobile
******************** */
@media (max-width: 600px) {
.page-title {
font-size: 2.5rem;
}
.page-header {
flex-direction: column;
align-items: center;
}
/* HEADER */
.main-nav {
font-size: 1rem;
margin-top: 10px;
}
.main-nav li {
margin: 0 20px;
}
/* HOME */
.home-content {
margin-top: 20%;
}
/* NEWS */
.news-contents {
flex-direction: column;
}
#news .page-title {
margin-top: 30px;
}
article,
aside {
width: 100%;
}
aside {
margin-top: 60px;
}
.post-info {
margin-bottom: 30px;
}
.post-date {
width: 70px;
height: 70px;
font-size: 1rem;
}
.post-date span {
font-size: 0.875rem;
padding-top: 2px;
}
.post-title {
font-size: 1.375rem;
}
.post-cat {
font-size: 0.875rem;
margin-top: 10px;
}
.post-title,
.post-cat {
margin-left: 80px;
}
/* MENU */
.menu-content {
margin-top: 20%;
}
/* CONTACT */
#contact .page-title {
margin-top: 40px;
}
/*Forme*/
input[type="text"],
input[type="email"],
textarea {
max-width: 100%;
}
/*Informations sur le magasin / carte/ SNS */
#location .wrapper,
#sns .wrapper {
flex-direction: column;
}
.location-info,
.location-map,
.sns-box {
width: 100%;
}
.sns-box {
margin-bottom: 30px;
}
}
Maintenant, créons un formulaire de connexion utilisateur. Cette fois, nous allons créer une fonction qui vous permet de publier un blog en vous connectant. Ce serait un problème si quelqu'un pouvait publier, modifier ou supprimer un blog, alors créez un code HTML qui gère la fonction d'authentification de l'utilisateur afin que seules les personnes connaissant l'ID utilisateur et le mot de passe puissent y accéder.
html:./cafe_site/templates/login.html
{% extends "theme.html" %}
{% block title %}Coffee House{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block content %}
{% for message in get_flashed_messages() %}
<div class="alert">
<font color="red">
<p>※{{ message }}</p>
</font>
</div>
{% endfor %}
{% endblock %}
{% block content2 %}
<form action="{{ url_for('login') }}" method=post>
<div>
<label for="InputTitle">Nom d'utilisateur</label>
<input type="text" id="InputTitle" name=username>
</div>
<div>
<label for="InputPassword">mot de passe</label>
<input type="password" id="InputPassword" name=password>
</div>
<input type="submit" class="button" value="S'identifier">
</form>
{% endblock %}
View Ensuite, nous ajouterons le traitement lors de l'accès à l'URL. Dans views.py, le processus de routage et la méthode de processus qui lui est associée sont décrits. Ici, nous ajouterons une vue pour la connexion et la déconnexion et ajouterons une fonction ** flash ** pour informer l'utilisateur du traitement de la ** session **, de la connexion et de la déconnexion.
Cette fois, le traitement suivant est réalisé.
Dans views.py, enregistrez le résultat que vous souhaitez afficher en fonction de chaque action en flash et modifiez-le afin qu'il puisse être renvoyé au client.
views.py
from flask import request, redirect, url_for, render_template, flash, session
from cafe_site import app
@app.route('/')
def index():
return render_template('cafe_site/index.html', id="home")
@app.route('/menu')
def menu():
return render_template('cafe_site/menu.html', id="menu")
@app.route('/news')
def news():
return render_template('cafe_site/news.html', id="news")
@app.route('/contact')
def contact():
return render_template('cafe_site/contact.html', id="contact")
@app.route('/review', methods=['GET'])
def review():
return render_template('cafe_site/review.html', id="review")
@app.route('/review', methods=['POST'])
def view_board():
if request.form['star'] and request.form['title'] and request.form['review']:
return render_template('cafe_site/review.html', name=app.config['USERNAME'], star=request.form['star'], title=request.form['title'], review=request.form['review'])
@app.route('/review')
def show_entries():
if not session.get('logged_in'):
return redirect(url_for('login'))
return render_template('cafe_site/review.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != app.config['USERNAME']:
flash('Le nom d'utilisateur est différent')
elif request.form['password'] != app.config['PASSWORD']:
flash('Le mot de passe est différent')
else:
session['logged_in'] = True
flash('Vous êtes maintenant connecté')
return redirect(url_for('show_entries'))
return render_template('login.html')
@app.route('/logout')
def logout():
session.pop('logged_in', None)
flash('déconnecté')
return redirect(url_for('show_entries'))
Flask peut gérer les informations de session en gérant la variable de session. Dans ** / login **, la valeur de logs_in pendant la session est définie sur True en définissant session ['logs_in'] = True après une connexion réussie. Désormais, vous pouvez déterminer si vous êtes connecté en vérifiant cette valeur à chaque demande. Après vous être déconnecté, supprimez les informations de session. Assurez-vous de le supprimer en tant que session.pop ('log_in', Aucun).
La fonction flash ajoute une ligne au flash («connecté») flash («déconnecté»), respectivement, lorsque la connexion est réussie et lorsque la déconnexion est effectuée. Le message est maintenant ajouté à la zone flash et vous pouvez transmettre le message au navigateur.
Définissez la clé secrète dans config.py. Cette clé secrète est utilisée pour crypter les informations de session.
python:./cafe_site/config.py
DEBUG = True
SECRET_KEY = 'bjgc5ejrwgwk'
USERNAME = 'syuuhei'
PASSWORD = 'abc123'
Modifiez theme.html pour modifier le lien affiché dans la barre de navigation selon que vous êtes connecté ou non.
theme.html
<nav>
<ul class="main-nav">
{% if not session.logged_in %}
<li><a href="/news">News</a></li>
<li><a href="/menu">Menu</a></li>
<li><a href="/contact">Contact</a></li>
<li><a href="/login">login</a></li>
{% else %}
<li><a href="/news">News</a></li>
<li><a href="/menu">Menu</a></li>
<li><a href="/contact">Contact</a></li>
<li><a href="/review">Review</a></li>
<li><a href="/logout">logout</a></li>
{% endif %}
</ul>
</nav>
theme.html
{% if not session.logged_in %}
Traitement sans connexion
{% else %}
Traitement lors de la connexion
{% endif %}
Le lien de connexion s'affiche lorsque vous n'êtes pas connecté et le lien de déconnexion s'affiche lorsque vous êtes connecté.
La suite sera expliquée dans Créer une application web avec Flask②.
Recommended Posts