記錄和測試前端(angualr)和後端(python)的基本使用 先在MariaDB上建立資料庫名userdb
建立資料表
1 2 3 4 5 6 7 CREATE TABLE `tbl_user` ( `user_id` bigint(20) NOT NULL AUTO_INCREMENT, `user_name` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL, `user_email` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL, `user_password` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (`user_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
導入flask-marshmallow 透過此函式庫可以讓我們的程式在處理請求參數更彈性
1 pip install -U marshmallow
Flask-CORS使用 1 2 3 from flask_cors import CORSCORS(app)
安裝
1 pip install -U flask-cors
建立python的restful的API 先建立crud_user.py
為執行python的主執行程式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 from flask import Flask, request, redirect, jsonifyfrom flask_sqlalchemy import SQLAlchemyfrom flask_marshmallow import Marshmallowfrom flask_cors import CORSapp = Flask(__name__) CORS(app) app.config['SECRET_KEY' ] = 'Fianna' app.config['SQLALCHEMY_DATABASE_URI' ] = 'mysql://root:12345678@localhost:3306/userdb' app.config['SQLALCHEMY_TRACK_MODIFICATIONS' ] = True db = SQLAlchemy(app) ma = Marshmallow(app) class User (db.Model): __tablename__ = 'tbl_user' user_id = db.Column(db.Integer, nullable=False , primary_key=True , autoincrement=True ) user_name = db.Column(db.String(45 ), nullable=True ) user_email = db.Column(db.String(45 ), nullable=True ) user_password = db.Column(db.String(45 ), nullable=True ) def __init__ (self, username, useremail, userpassword="" ): self.user_name=username self.user_email=useremail self.user_password=userpassword def __repr__ (self ): return '<User %r,user_id %r>' % (self.user_name, self.user_id) class UserSchema (ma.Schema): class Meta : fields = ('user_id' , 'user_name' , 'user_email' , 'user_password' ) user_schema = UserSchema() users_schema = UserSchema(many=True ) @app.route("/user" , methods=["POST" ] ) def add_user (): try : username = request.json['user_name' ] email = request.json['user_email' ] password= request.json['user_password' ] new_user = User(username, email,password) db.session.add(new_user) db.session.commit() return user_schema.jsonify(new_user) except Exception as e: print ("Failed to add user" ) print (e) @app.route("/user" , methods=["GET" ] ) def get_user (): try : all_users = User.query.all () result = users_schema.dump(all_users) return jsonify(result.data) except Exception as e: print ("Failed to get all user" ) print (e) @app.route("/user/<id>" ,methods=["GET" ] ) def user_detail (id ): try : user = User.query.get(id ) return user_schema.jsonify(user) except Exception as e: print ("Failed to get user" ) print (e) @app.route("/user/<id>" , methods=["PUT" ] ) def user_update (id ): try : user = User.query.get(id ) username = request.json['user_name' ] email = request.json['user_email' ] password= request.json['user_password' ] user.user_name= username user.user_email = email user.user_password = password db.session.commit() return user_schema.jsonify(user) except Exception as e: print ("Failed to update user" ) print (e) @app.route("/user/<id>" , methods=["DELETE" ] ) def user_delete (id ): try : user = User.query.get(id ) db.session.delete(user) db.session.commit() return user_schema.jsonify(user) except : print ("Failed to del user" ) print (e) if __name__ == "__main__" : app.run(debug=False )
以上的程式碼分成幾部分
導入需要的程式庫和建利App物件
1 2 3 4 5 from flask import Flask, request, redirect, jsonifyfrom flask_sqlalchemy import SQLAlchemyfrom flask_marshmallow import Marshmallowapp = Flask(__name__)
有關資料庫相關
1 2 3 4 5 6 # 資料庫相關 app.config['SECRET_KEY'] = 'Fianna' app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:12345678@localhost:3306/userdb' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True db = SQLAlchemy(app) ma = Marshmallow(app)
有關ORM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class User (db.Model): __tablename__ = 'tbl_user' user_id = db.Column(db.Integer, nullable=False , primary_key=True , autoincrement=True ) user_name = db.Column(db.String(45 ), nullable=True ) user_email = db.Column(db.String(45 ), nullable=True ) user_password = db.Column(db.String(45 ), nullable=True ) def __init__ (self, username, useremail, userpassword="" ): self.user_name=username self.user_email=useremail self.user_password=userpassword def __repr__ (self ): return '<User %r,user_id %r>' % (self.user_name, self.user_id) class UserSchema (ma.Schema): class Meta : fields = ('user_id' , 'user_name' , 'user_email' , 'user_password' ) user_schema = UserSchema() users_schema = UserSchema(many=True )
有關C,建立使用者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @app.route("/user" , methods=["POST" ] ) def add_user (): try : username = request.json['user_name' ] email = request.json['user_email' ] password= request.json['user_password' ] new_user = User(username, email,password) db.session.add(new_user) db.session.commit() return user_schema.jsonify(new_user) except Exception as e: print ("Failed to add user" ) print (e)
有關R,讀取使用者和所有使用者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @app.route("/user" , methods=["GET" ] ) def get_user (): try : all_users = User.query.all () result = users_schema.dump(all_users) return jsonify(result.data) except Exception as e: print ("Failed to get all user" ) print (e) @app.route("/user/<id>" ,methods=["GET" ] ) def user_detail (id ): try : user = User.query.get(id ) return user_schema.jsonify(user) except Exception as e: print ("Failed to get user" ) print (e)
有關U,更新使用者資料
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @app.route("/user/<id>" , methods=["PUT" ] ) def user_update (id ): try : user = User.query.get(id ) username = request.json['user_name' ] email = request.json['user_email' ] password= request.json['user_password' ] user.user_name= username user.user_email = email user.user_password = password db.session.commit() return user_schema.jsonify(user) except Exception as e: print ("Failed to update user" ) print (e)
有關D,刪除使用者
1 2 3 4 5 6 7 8 9 10 11 @app.route("/user/<id>" , methods=["DELETE" ] ) def user_delete (id ): try : user = User.query.get(id ) db.session.delete(user) db.session.commit() return user_schema.jsonify(user) except : print ("Failed to del user" ) print (e)
建立Agnular測試端 先建立專案
在建立各個元件在user的目錄下
1 2 3 4 ng g c user/user-list ng g c user/user-add ng g c user/user-edit ng g c user/user-detail
在src\app\app-routing.module.ts
下來建立接下來的路由路徑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import { NgModule } from '@angular/core' ;import { Routes , RouterModule } from '@angular/router' ;import { UserListComponent } from './user/user-list/user-list.component' ;const routes : Routes = [ { path : '' , redirectTo : '/user' , pathMatch : 'full' }, { path : 'user' , component : UserListComponent } ]; @NgModule ({ imports : [RouterModule .forRoot (routes)], exports : [RouterModule ] }) export class AppRoutingModule { }
先測試路由和元件是否能顯示輸入http://localhost:4200/
會自動轉成http://localhost:4200/user
會顯示user-list的元件
建立使用者物件在user
的資料夾下src\app\user\user.ts
1 2 3 4 5 6 export class User { user_id?:number ; user_name :string ; user_email :string ; user_password :string ; }
建立服務物件在user
的資料夾下
在src\app\user\user.service.ts
下先加入列出所有的使用者服務
要先將使用的模塊加入到src\app\app.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import { HttpClientModule } from '@angular/common/http' ;@NgModule ({ declarations : [ AppComponent , ], imports : [ BrowserModule , HttpClientModule , AppRoutingModule ], providers : [], bootstrap : [AppComponent ] }) export class AppModule { }
顯示所有使用者 在src\app\user\user.service.ts
的服務引用,並在構造函數中聲明,因為有使用到user的物件也需要引用進來,因為使用Obserable所以也要引用進來,在加入取得所以的資料流
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import { Injectable } from '@angular/core' ;import { HttpClient ,HttpHeaders } from "@angular/common/http" ;import { User } from './user' ;import { Observable } from 'rxjs' ;@Injectable ({ providedIn : 'root' }) export class UserService { private userUrl = "http://localhost:5000" ; constructor (private http:HttpClient ) { } getUsers ():Observable <User []>{ var api = this .userUrl +"/user" ; return this .http .get <User []>(api); } }
在顯示端src\app\user\user-list\user-list.component.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <h3 > 使用者列表</h3 > <div > </div > <table > <tr > <th > ID</th > <th > Name</th > <th > Email</th > <th > Actions</th > </tr > <tr *ngFor ="let user of users" > <td > {{user.user_id}}</td > <td > {{user.user_name}}</td > <td > {{user.user_email}}</td > <td > notimp</td > </tr > </table >
加入使用者 因為要加入雙向綁定所以要加入FormsModule 模組
1 import { FormsModule } from '@angular/forms' ;
在路由端要加入src\app\app-routing.module.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import { NgModule } from '@angular/core' ;import { Routes , RouterModule } from '@angular/router' ;import { UserListComponent } from './user/user-list/user-list.component' ;import { UserAddComponent } from './user/user-add/user-add.component' ;const routes : Routes = [ { path : '' , redirectTo : '/user' , pathMatch : 'full' }, { path : 'user' , component : UserListComponent }, { path : 'add' , component : UserAddComponent } ]; @NgModule ({ imports : [RouterModule .forRoot (routes)], exports : [RouterModule ] }) export class AppRoutingModule { }
在服務端src\app\user\user.service.ts
中要加入HttpHeaders 的物件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import { Injectable } from '@angular/core' ;import { HttpClient ,HttpHeaders } from "@angular/common/http" ;import { User } from './user' ;import { Observable } from 'rxjs' ;const httpOptions = { headers : new HttpHeaders ({ 'Content-Type' : 'application/json' }) }; @Injectable ({ providedIn : 'root' }) export class UserService { private userUrl = "http://localhost:5000" ; constructor (private http:HttpClient ) { } getUsers ():Observable <User []>{ var api = this .userUrl +"/user" ; return this .http .get <User []>(api); } addUser (user : User ): Observable <User > { var api = this .userUrl + "/user" ; return this .http .post <User >(api, user, httpOptions); } }
在src\app\user\user-add\user-add.component.ts
中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import { Component , OnInit } from '@angular/core' ;import { Location } from '@angular/common' ;import { User } from '../user' ;import { UserService } from '../user.service' ;@Component ({ selector : 'app-user-add' , templateUrl : './user-add.component.html' , styleUrls : ['./user-add.component.scss' ] }) export class UserAddComponent implements OnInit { public user : User = new User (); constructor (private usersevice:UserService,private location:Location ) { } ngOnInit ( ) { } save ():void { this .usersevice .addUser (this .user ).subscribe ((res )=> { console .log (res); this .goBack ()}); } goBack ():void { this .location .back (); } }
在顯示端src\app\user\user-add\user-add.component.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <div > <h2 > 加入使用者</h2 > <p > <label > 姓名:<input [(ngModel )]="user.user_name" placeholder ="請輸人姓名" > </label > </p > <p > <label > Email:<input [(ngModel )]="user.user_email" placeholder ="請輸人email" > </label > </p > <p > <label > 密碼:<input type ="password" [(ngModel )]="user.user_password" placeholder ="請輸人密碼" > </label > </p > <button (click )="goBack()" > 回到上一頁</button > <button (click )="save()" > 加入</button > </div >
顯示一個使用者 在路由上加上顯示使用者src\app\app-routing.module.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import { NgModule } from '@angular/core' ;import { Routes , RouterModule } from '@angular/router' ;import { UserListComponent } from './user/user-list/user-list.component' ;import { UserAddComponent } from './user/user-add/user-add.component' ;import { UserDetailComponent } from './user/user-detail/user-detail.component' ;const routes : Routes = [ { path : '' , redirectTo : '/user' , pathMatch : 'full' }, { path : 'user' , component : UserListComponent }, { path : 'add' , component : UserAddComponent }, { path : 'detail/:id' , component : UserDetailComponent } ]; @NgModule ({ imports : [RouterModule .forRoot (routes)], exports : [RouterModule ] }) export class AppRoutingModule { }
在路由顯示端src\app\user\user-list\user-list.component.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <h3 > 使用者列表</h3 > <div > <a [routerLink ]="['/add']" > 加入使用者</a > </div > <table > <tr > <th > ID</th > <th > Name</th > <th > Email</th > <th > Actions</th > </tr > <tr *ngFor ="let user of users" > <td > {{user.user_id}}</td > <td > {{user.user_name}}</td > <td > {{user.user_email}}</td > <td > <a routerLink ="/detail/{{user.user_id}}" > 使用者資訊</a > </td > </tr > </table >
先在服務端src\app\user\user.service.ts
加入以id來取得使用者資訊
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import { Injectable } from '@angular/core' ;import { HttpClient , HttpHeaders } from "@angular/common/http" ;import { User } from './user' ;import { Observable } from 'rxjs' ;const httpOptions = { headers : new HttpHeaders ({ 'Content-Type' : 'application/json' }) }; @Injectable ({ providedIn : 'root' }) export class UserService { private userUrl = "http://localhost:5000" ; constructor (private http: HttpClient ) { } getUsers (): Observable <User []> { var api = this .userUrl + "/user" ; return this .http .get <User []>(api); } addUser (user : User ): Observable <User > { var api = this .userUrl + "/user" ; return this .http .post <User >(api, user, httpOptions); } getUser (id : string ):Observable <User >{ var api = `${this .userUrl} /user/${id} ` ; return this .http .get <User >(api); } }
在src\app\user\user-detail\user-detail.component.ts
中加入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import { Component , OnInit } from '@angular/core' ;import { Location } from '@angular/common' ;import { ActivatedRoute } from '@angular/router' ;import { User } from '../user' ;import { UserService } from '../user.service' ;@Component ({ selector : 'app-user-detail' , templateUrl : './user-detail.component.html' , styleUrls : ['./user-detail.component.scss' ] }) export class UserDetailComponent implements OnInit { user : User ; constructor (private route: ActivatedRoute, private userService: UserService, private location: Location ) { } ngOnInit ( ) { this .getUser (); } getUser (): void { const id = this .route .snapshot .paramMap .get ('id' ); this .userService .getUser (id).subscribe ((data ) => { this .user = data; }); } goBack (): void { this .location .back (); } }
在顯示端src\app\user\user-detail\user-detail.component.html
1 2 3 4 5 6 7 8 9 10 11 12 13 <div *ngIf ="user" > <h2 > {{user.user_name | uppercase }} 細節</h2 > <div > <span > Id:</span > {{user.user_id}}</div > <div > <p > Name: {{user.user_name}} </p > <p > Email: {{user.user_email}} </p > </div > <button (click )="goBack()" > go back</button > </div >
編輯一個使用者 在路由上加上顯示使用者src\app\app-routing.module.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import { NgModule } from '@angular/core' ;import { Routes , RouterModule } from '@angular/router' ;import { UserListComponent } from './user/user-list/user-list.component' ;import { UserAddComponent } from './user/user-add/user-add.component' ;import { UserDetailComponent } from './user/user-detail/user-detail.component' ;import { UserEditComponent } from './user/user-edit/user-edit.component' ;const routes : Routes = [ { path : '' , redirectTo : '/user' , pathMatch : 'full' }, { path : 'user' , component : UserListComponent }, { path : 'add' , component : UserAddComponent }, { path : 'detail/:id' , component : UserDetailComponent }, { path : 'edit/:id' , component : UserEditComponent } ]; @NgModule ({ imports : [RouterModule .forRoot (routes)], exports : [RouterModule ] }) export class AppRoutingModule { }
在路由顯示端src\app\user\user-list\user-list.component.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <h3 > 使用者列表</h3 > <div > <a [routerLink ]="['/add']" > 加入使用者</a > </div > <table > <tr > <th > ID</th > <th > Name</th > <th > Email</th > <th > Actions</th > </tr > <tr *ngFor ="let user of users" > <td > {{user.user_id}}</td > <td > {{user.user_name}}</td > <td > {{user.user_email}}</td > <td > <a routerLink ="/detail/{{user.user_id}}" > 使用者資訊</a > <a routerLink ="/edit/{{user.user_id}}" > 編輯使用者資訊</a > </td > </tr > </table >
先在服務端src\app\user\user.service.ts
加入以傳入user來編輯使用者資訊
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 import { Injectable } from '@angular/core' ;import { HttpClient , HttpHeaders } from "@angular/common/http" ;import { User } from './user' ;import { Observable } from 'rxjs' ;const httpOptions = { headers : new HttpHeaders ({ 'Content-Type' : 'application/json' }) }; @Injectable ({ providedIn : 'root' }) export class UserService { private userUrl = "http://localhost:5000" ; constructor (private http: HttpClient ) { } getUsers (): Observable <User []> { var api = this .userUrl + "/user" ; return this .http .get <User []>(api); } addUser (user : User ): Observable <User > { var api = this .userUrl + "/user" ; return this .http .post <User >(api, user, httpOptions); } getUser (id : string ):Observable <User >{ var api = `${this .userUrl} /user/${id} ` ; return this .http .get <User >(api); } updateUser (user :User ):Observable <User >{ var api = `${this .userUrl} /user/${user.user_id} ` ; return this .http .put <User >(api,user,httpOptions); } }
在src\app\user\user-edit\user-edit.component.ts
中加入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 import { Component , OnInit } from '@angular/core' ;import { Location } from '@angular/common' ;import { ActivatedRoute } from '@angular/router' ;import { User } from '../user' ;import { UserService } from '../user.service' ;@Component ({ selector : 'app-user-edit' , templateUrl : './user-edit.component.html' , styleUrls : ['./user-edit.component.scss' ] }) export class UserEditComponent implements OnInit { user : User ; constructor (private route: ActivatedRoute, private userService: UserService, private location: Location ) { } ngOnInit ( ) { this .getUser (); } getUser ( ) { const id = this .route .snapshot .paramMap .get ('id' ); this .userService .getUser (id).subscribe ((data ) => { this .user = data; }); } save ():void { this .userService .updateUser (this .user ).subscribe ((success )=> { this .goBack (); }); } goBack (): void { this .location .back (); } }
在顯示端src\app\user\user-edit\user-edit.component.html
1 2 3 4 5 6 7 8 9 10 11 12 13 <div *ngIf ="user" > <h2 > {{user.user_name | uppercase }} 細節</h2 > <div > <span > Id:</span > {{user.user_id}}</div > <div > <p > Name: {{user.user_name}} </p > <p > Email: {{user.user_email}} </p > </div > <button (click )="goBack()" > go back</button > </div >
刪除一個使用者 先在服務端src\app\user\user.service.ts
加入以傳入user來刪除使用者資訊
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 import { Injectable } from '@angular/core' ;import { HttpClient , HttpHeaders } from "@angular/common/http" ;import { User } from './user' ;import { Observable } from 'rxjs' ;const httpOptions = { headers : new HttpHeaders ({ 'Content-Type' : 'application/json' }) }; @Injectable ({ providedIn : 'root' }) export class UserService { private userUrl = "http://localhost:5000" ; constructor (private http: HttpClient ) { } getUsers (): Observable <User []> { var api = this .userUrl + "/user" ; return this .http .get <User []>(api); } addUser (user : User ): Observable <User > { var api = this .userUrl + "/user" ; return this .http .post <User >(api, user, httpOptions); } getUser (id : string ):Observable <User >{ var api = `${this .userUrl} /user/${id} ` ; return this .http .get <User >(api); } updateUser (user :User ):Observable <User >{ var api = `${this .userUrl} /user/${user.user_id} ` ; return this .http .put <User >(api,user,httpOptions); } deleteUser (user :User ):Observable <User >{ var api = `${this .userUrl} /user/${user.user_id} ` ; return this .http .delete <User >(api); } }
在src\app\user\user-list\user-list.component.ts
元件中加入刪除使用者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import { Component , OnInit } from '@angular/core' ;import { Location } from '@angular/common' ;import { UserService } from '../user.service' ;import { Subscriber } from 'rxjs' ;import { User } from '../user' ;@Component ({ selector : 'app-user-list' , templateUrl : './user-list.component.html' , styleUrls : ['./user-list.component.scss' ] }) export class UserListComponent implements OnInit { users : User [] = []; constructor (private uservice:UserService,private location: Location ) { } ngOnInit ( ) { this .getUsers (); } getUsers ():void { this .uservice .getUsers ().subscribe ((users )=> { this .users =users; }); } delete (user :User ):void { if (confirm ("Are you sure to delete?" )) { this .uservice .deleteUser (user).subscribe (()=> { window .location .reload (); }); } } }
在顯示端加入src\app\user\user-list\user-list.component.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <h3 > 使用者列表</h3 > <div > <a [routerLink ]="['/add']" > 加入使用者</a > </div > <table > <tr > <th > ID</th > <th > Name</th > <th > Email</th > <th > Actions</th > </tr > <tr *ngFor ="let user of users" > <td > {{user.user_id}}</td > <td > {{user.user_name}}</td > <td > {{user.user_email}}</td > <td > <a routerLink ="/detail/{{user.user_id}}" > 使用者資訊</a > <a routerLink ="/edit/{{user.user_id}}" > 編輯使用者資訊</a > <button (click )="delete(user)" > X</button > </td > </tr > </table >
可以參考https://github.com/ttom921/StudyPython.git裏的TestFlaskAngular的專案
參考資料 Build Simple Restful Api With Python and Flask Part 2 Python REST API CRUD Example using Flask and MySQL Python REST APIs + Flask + Angular CRUD Example