はじめに
今日のソースはフロントエンド側の話。。。
WEBアプリ開発においては、JAVASCRIPTの習得が必須。
これはバックエンド+フロントエンド=WEBアプリみたいに、
対で成立するものであって、どっちがどうとか言う問題ではない。
つまりFLASKをPYTHONのライブラリと思っていれば良いという事でなく、
FLASK=PYTHON+JAVASCRIPTということ
(ここでHTML,CCSのことは、必要最低限できているのが前提にあるが)
参考ソース
Python(FLASK) - SQLite で発見
https://github.com/zeeshanshamsuddeen/Online-Food-Ordering-System
テンプレート
ルーティングの際に静的ファイルは、STATICというフォルダに入れるらしい
url_forの指定の仕方は、'static'+ファイル名 で書かないと、だめらしい
実はここで、つまずいていたが、下記のソースを見て明らかになった。
https://github.com/zeeshanshamsuddeen/Online-Food-Ordering-System/blob/master/templates/customer.html
<!DOCTYPE html>
<html >
<head>
<link type="text/css" href="{{url_for('static',filename='省略.css')}}" rel="stylesheet"/>
<link rel="stylesheet" href="{{url_for('static',filename='省略.css')}}">
<script type="text/javascript" src="{{url_for('static',filename='ライブラリ.js')}}"></script>
<link rel="stylesheet" href="{{url_for('static',filename='ライブラリ.css')}}">
ログイン処理
このソースを見て、プロフェッショナルの仕事だと実感。
JAVASCRIPTの達人であれば、すべてフロントエンドでログイン認証まで完了できてしまう。
(ちなみにJQUERYは使っていない)
データベースから、ユーザー名、パスワードが対になった、リストを持ってきている。
ここではテンプレート側で、ループを組んでいて{% ループ in VAR %}は
FLASK側から持ってきたリスト変数VARである。
JSの型宣言のVARと、変数のVARが被ってる。なぜこんな変数名にしたのか疑問!
function ログイン判定(){
var username=document.forms[フォーム]["username"].value; → フォームから取得
var password=document.forms[フォーム]["password"].value; → フォームから取得
var x=0;
if(username=="") { alert("ユーザ名を催促"); document.form1.action=""; }
else if(password=="") { alert("パスワードを催促"); document.form1.action=""; }
else {
{% for x in var %}
if(username=="{{x[0]}}" && password=="{{x[1]}}") { x=1; }
{% endfor %}
if(x==1){alertify.log( "welcome "+username, "success" );
document.form1.action="http://localhost:8080/ログイン処理";
document.form1.method="post"; → ポストさせる
}else{
alert("拒否メッセージ");
document.form1.action=""; → ポストさせない
}}}
こんな感じで、ローカルホストのポートまでJSに突っ込んで、
ポストのリクエストまで、直接書き換えてしまう。
とりあえず動いたらええんや!って感じ。
<h2>ログイン</h2>
<button class="btn_login" onclick="login()">LOGIN</button>
<h2>サインアップ</h2>
<button class="btn_sign_up" onclick="sign_up()">SIGN UP</button>
<a href="#" onclick="共通処理" ><i class="material-icons">←</i></a>
<h2>LOGIN</h2>
<form name='form1' onsubmit="required_login()">
<br>
<input class="login_space" type="text" name="username" placeholder="Username">
<input class="login_space" type="password" name="password" placeholder="Password">
<button class="btn_login" type="submit" name="submit" value="Sign in" />SIGN IN</button>
</form>
<a href="#" onclick="共通処理"><i class="material-icons">←</i></a>
<h2>SIGN UP</h2>
<form name='form2' onsubmit="required_signup()">
<br>
<input class="login_space" type="text" name="username" placeholder="Username" >
<input class="login_space" type="password" name="password" placeholder="Password" >
<input class="login_space" type="password" name="password2" placeholder="Confirm Password" >
<button class="btn_sign_up" type="submit" name="submit" value="Sign up" />SIGN UP</button>
</form>
最初のメニューで、ログインとサインアップのどちらかを選ばせて、
サブウィンドウを出させて、そこでログイン、サインアップ処理をさせている。
この時点で、バックエンドに処理をさせずに、フロントエンド側で対処できるとは、しらなんだ。。。
マテリアルアイコンがJS側での、パスワードの見せる、見せないを示すアイコンだが
これも、こんな簡単な仕組みで実装できるなんて驚愕(もっと何かやっていると思っていた)
見栄えのトリック
JAVASCRIPTを使って、画面にぬるっと出す処理。
この辺は、骨格ができてからの最終段階だと思うが・・・
最初はなくても動く
あと重文が続いており、JQUERYが開発された理由が分かった。
function ログイン処理() {
document.querySelector().className = "";
document.querySelector().style.display = "block";
document.querySelector().style.opacity = "0";
setTimeout(function(){ document.querySelector( ).style.opacity = "1"; },400);
setTimeout(function(){ document.querySelector( ).style.display = "none";},200); }
function サインアップ処理() {
document.querySelector().className = "";
document.querySelector().style.display = "block";
document.querySelector().style.opacity = "0";
setTimeout(function(){ document.querySelector().style.opacity = "1";},100);
setTimeout(function(){ document.querySelector().style.display = "none";},400); }
function 共通() {
document.querySelector().className = "cont_forms";
document.querySelector().style.opacity = "0";
document.querySelector().style.opacity = "0";
setTimeout(function(){
document.querySelector().style.display = "none";
document.querySelector().style.display = "none";
},500); }
バックエンド
お次はバックエンド側
ごり押しで触ってみる
データベースは既に作成ずみというのが前提
(わざわざDBメンテナンスまで、PYTHONで書かなくてもいいことを発見)
@app.route('/カスタマ')
def customer():
conn=sqlite3.connect('データベース.db')
cur=conn.cursor()
cur.execute("SELECT * FROM ちょめちょめ")
var=cur.fetchall()
conn.close()
return render_template('カスタマ.html',var=var)
@app.route('/サイン',methods=['GET','POST'])
def サインアップ():
session['username']=request.form['username']
password=request.form['password']
conn=sqlite3.connect('データベース.db')
cur=conn.cursor()
cur.execute("INSERT INTO customers(username,password) VALUES (?,?)",(session['username'],password))
cur.execute("CREATE TABLE {}( チョメチョメ )".format(session['username']))
temp=session['username']+'_orders'
cur.execute("CREATE TABLE IF NOT EXISTS {}(チョメチョメ);".format(temp))
conn.commit()
return redirect(url_for('メイン'))
@app.route('/ログイン',methods=['GET','POST'])
def ログイン():
session['username']=request.form['username']
return redirect(url_for('homepage_customer'))
@app.route('/メイン')
def メイン():
conn=sqlite3.connect('members.db')
cur=conn.cursor()
cur.execute("SELECT * FROM response WHERE username=?",(session['username'],))
response=cur.fetchall()
cur.execute("SELECT * FROM most_ordered ORDER BY orders DESC limit 4")
most_ordered=cur.fetchall()
conn.close()
return render_template('メイン.html',response=response,most_ordered=most_ordered)
サインアップ見てびびる。
ユーザー名でテーブル作ってるやんか・・・
これってアンチやんか!・・・
あとSQL・・・ かろうじてアクセス触っていたから読める・・・
(読むことはできても、書くことは別世界)
とりあえず、ログインさせてメインページまで、入るところがイメージングできた。
ログイン後は、下記でセッション登録している。
session['username']=request.form['username']