design sketch:
preface
Before we start, let's talk about Django and Flask. Compare the decoration style: one is light luxury style (left in the figure below) and the other is Syrian style (right in the figure below):
Django is more comfortable to use. It is probably the "bag check-in" mode in the mouth of the tenant. It has complete tools. You only need to consider whether to eat roujiamo (CBV) or 4 dishes and 1 soup (FBV). Occasionally, you have to consider whether it is appropriate to change a refrigerator (database).
Using Flask is like finding a Syrian style rental house. It looks very simple. In fact, it has everything (referring to the floor and ceiling). However, if you want to have a different flavor, you have to decorate it according to your own preferences.
Decoration link
1. Flooring (written by flash basic style)
Coding tools depend on your preference. I use Visio Studio Code here, due to the use of vue framework, we should distinguish Flask from vue at the beginning and arrange a single private room for them. In other words, create two folders and store the front and back codes separately.
Create a new app in the backend folder Py as our back-end main program, write in it:
from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): return "<p>Hello, World!</p>"
It's probably like this:
Then we open the console, enter the flash folder, and enter the following code:
set FLASK_APP=app.py # Set the flash environment variable if the name is app Py or WSGI Py can ignore this code flask run # start-up
You can see that the console outputs an IP and opens it in the browser:
* Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
2. Select a storage room (database)
Here, I choose Flask + SQLAlchemy + SQLite as our data storage system, and import SQLAlchemy into the app:
from flask_sqlalchemy import SQLAlchemy
Create a table according to the fields we need:
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.sqlite' # Specify database file app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True # Allows you to modify the tracking database db = SQLAlchemy(app) class Books(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(80), nullable=False) author = db.Column(db.String(120), nullable=False) read= db.Column(db.Boolean) db.create_all() # Create table
Rerun app Py file, you can see that the database file has been generatedNext, we define several functions to facilitate the addition, deletion, modification and query of the database:
# increase def insertData(title,author,read): book=Books(title=title,author=author,read=read) db.session.add_all([book]) db.session.commit() # check def selectDataAll(): book_list=[] books = Books.query.all() # Similar to select * from Books for s in books: dic = {} dic['id'] = s.id dic['title'] = s.title dic['author'] = s.author dic['read'] = s.read print(f'Id: {s.id} | Title: {s.title} | Author: {s.author} | Read: {s.read}') print('----') book_list.append(dic) return book_list # Delete def deleteData(id): book = Books.query.get(id) # Similar to select * from Books where id = id db.session.delete(book) db.session.commit() # Submit operation to database # change def updateData(id, title='', author='', read='', new_id=''): book = Books.query.get(id) if not title=='': book.title = title if not author == '': book.author = author if not read == '': book.read = read if not new_id == '': book.id=new_id db.session.commit()
Add data using the increment function we have written:
··· insertData('book1','zhangsan',0) insertData('book2','lisi',1) ···
Run app After py, the data is added to the database.
#Ps: after running, remember to use the app Delete the above two sentences in py
3. Install doors and windows (accept the specified interactive information and respond)
··· from flask import Flask, jsonify, request, make_response ··· ··· @app.route('/',methods=['GET','POST']) def all_books(): response_object = {'status':'success'} books = selectDataAll() response_object['books']=books return jsonify(response_object) ···
Everything is ready, we run the app Py, you can see that the data in the database has been displayed in the web page:
4. Exterior wall decoration
First, configure the required application and environment according to the following process:
1. We need node in our computer JS (Chinese web address: http://nodejs.cn/ ), download and install directly (installation tutorial: https://www.runoob.com/nodejs/nodejs-install-setup.html ).
2. Install cnpm (cmd input: NPM install - G cnpm -- Registry)= http://registry.npm.taobao.org )
3. Install vue scaffold (cmd input: NPM install - G vue CLI)
4. Install webpack (cmd input: npm install webpack -g)
5. Find the vue folder we created earlier, cd it, cmd enter: vue create file name, and then an interface will appear:
The first option is the configuration saved in the past
The second is the default configuration
The third is custom (select features manually)
We select custom configuration, the up and down arrows on the keypad move, and the space is checked / unchecked.
Here we all choose.
Then press enter to proceed to the next stage:
#Ps: Note: the last item means whether to use the above configuration for future projects (save the configuration)
After installation, enter cmd under the root directory of vue and enter npm run serve
#Ps: if it fails, please check the package. In the root directory JSON file, and try to start using the npm run dev instruction
Start successfully, as shown in the figure below:
5. House renovation (linkage and optimization of front and rear ends, problem handling)
At this stage, we are almost at the end. By observing the renderings, we can conclude that the tools we need are:
vue:
- Bootstrap # comes with its own style and is easy to use (cmd input in vue root directory: npm install bootstrap --save)
- axios # is used to solve cross domain problems (cmd input under the root directory of vue: npm; install axios)
Flask:
- CORS # is used to solve cross domain problems (cmd input: PIP3 install flash_cors)
After installing axios on the front end, use axios Post is a way to handle cross domain interactions
After installing the above tools, we will start the final work.
1. Modify the app. In the flash folder Py (configure cross domain interaction):
··· from flask_cors import CORS # Import CORS package ··· ··· @app.after_request def after(resp): resp = make_response(resp) resp.headers['Access-Control-Allow-Origin'] = '*' # Allow cross domain addresses resp.headers['Access-Control-Allow-Methods'] = '*' # Request '*' is all resp.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type' # head resp.headers['Access-Control-Allow-Credentials'] = 'True' return resp CORS(app, resources=r'/*', supports_credentials=True) ···
2. Create alert in src / components under vue folder vue files and books vue file
3. Configure router / index JS (or index.ts)
import Vue from "vue"; import VueRouter, { RouteConfig } from "vue-router"; import Books from "../components/Books.vue"; import Home from "../components/HelloWorld.vue"; import 'bootstrap/dist/css/bootstrap.css'; import BootstrapVue from 'bootstrap-vue' Vue.config.productionTip=false Vue.use(BootstrapVue); Vue.use(VueRouter); const routes: Array<RouteConfig> = [ { path: "/home", name: "Home", component: Home, }, { path: "/", # Add books Add Vue to the route name: "Books", component: Books, }, { path: "/about", name: "About", // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ "../views/About.vue"), }, ]; const router = new VueRouter({ mode: "history", base: process.env.BASE_URL, routes, }); export default router;
4. Configure books Vue and alert vue
# Books.vue <template> <div class="container" align="left"> <div class="row"> <div class="col-sm-10"> <h1>Books</h1> <hr /> <br /> <div> <b-alert variant="success" show>{{ message }}</b-alert> <br> </div> <br /> <button type="button" class="btn btn-success btn-sm">Add Book</button> <br /> <br /> <table class="table table-hover"> <thead> <tr> <th scope="col">Title</th> <th scope="col">Author</th> <th scope="col">Read?</th> <th></th> </tr> </thead> <tbody> <tr v-for="(book, index) in books" :key="index"> <td>{{ book.title }}</td> <td>{{ book.author }}</td> <td> <span v-if="book.read">Yes</span> <span v-else>No</span> </td> <td> <div class="btn-group" role="group"> <button type="button" class="btn btn-warning">Update</button> <button type="button" class="btn btn-danger">Delete</button> </div> </td> </tr> </tbody> </table> </div> </div> </div> </template> <script> import axios from "axios"; import Alert from './Alert.vue' export default { data() { return { props: ['message'], books: [], BookForm: { delbook:"", id: "", title: "", author: "", read: [] }, message: '', }; }, commponents:{ alert:Alert, }, methods: { getBooks() { const path="http://127.0.0.1:5000"; axios .get(path) .then(res => { this.books=res.data.books; }) .catch(error => { console.error(error); }); }, initForm() { this.BookForm.delbook='null'; this.BookForm.id="null"; this.BookForm.title=""; this.BookForm.author=""; this.BookForm.read=[]; }, }, created() { this.getBooks(); } }; </script>
# Alert.vue <template><div></div></template>
In books In Vue, we mainly build the basic framework of web pages. At present, we can only obtain the data in the database and display:
Next, we begin to write the code for the Add Book button:
<template> <div class="container" align="left"> <div class="row"> <div class="col-sm-10"> <h1>Books</h1> <hr /> <br /> <div> <b-alert variant="success" show>{{ message }}</b-alert> <br> </div> <br /> <button type="button" class="btn btn-success btn-sm" v-b-modal.book-add>Add Book</button> <br /> <br /> <table class="table table-hover"> <thead> <tr> <th scope="col">Title</th> <th scope="col">Author</th> <th scope="col">Read?</th> <th></th> </tr> </thead> <tbody> <tr v-for="(book, index) in books" :key="index"> <td>{{ book.title }}</td> <td>{{ book.author }}</td> <td> <span v-if="book.read">Yes</span> <span v-else>No</span> </td> <td> <div class="btn-group" role="group"> <button type="button" class="btn btn-warning">Update</button> <button type="button" class="btn btn-danger">Delete</button> </div> </td> </tr> </tbody> </table> </div> </div> <!-- --------------------------------Add------------------------------ --> <!-- Note that with the above Add Book Button binding --> <b-modal ref="addBookModal" id="book-add" title="Add a new book" hide-footer> <b-form @submit="add_onSubmit" @reset="add_onReset" class="w-100"> <b-form-group id="form-title-group" label="Title:" label-for="form-title-input"> <b-form-input id="form-title-input" type="text" v-model="BookForm.title" required placeholder="Enter title" ></b-form-input> </b-form-group> <b-form-group id="form-author-group" label="Author:" label-for="form-author-input"> <b-form-input id="form-author-input" type="text" v-model="BookForm.author" required placeholder="Enter author" ></b-form-input> </b-form-group> <b-form-group id="form-read-group"> <b-form-checkbox-group v-model="BookForm.read" id="form-checks"> <b-form-checkbox value="true">Read?</b-form-checkbox> </b-form-checkbox-group> </b-form-group> <b-button-group> <b-button type="submit" variant="primary">Submit</b-button> <b-button type="reset" variant="danger">Reset</b-button> </b-button-group> </b-form> </b-modal> </div> </template>
And the corresponding script code:
<script> import axios from "axios"; import Alert from './Alert.vue' export default { data() { return { props: ['message'], books: [], BookForm: { delbook:"", id: "", title: "", author: "", read: [] }, message: '', }; }, commponents:{ alert:Alert, }, methods: { getBooks() { const path="http://127.0.0.1:5000"; axios .get(path) .then(res => { this.books=res.data.books; }) .catch(error => { console.error(error); }); }, initForm() { this.BookForm.delbook='null'; this.BookForm.id="null"; this.BookForm.title=""; this.BookForm.author=""; this.BookForm.read=[]; }, // --------------------------Add----------------------------- addBook(payload) { const path="http://127.0.0.1:5000"; axios .post(path, payload) .then(() => { this.getBooks(); this.message = 'Book added!' }) .catch(error => { console.log(error); this.getBooks(); }); }, add_onSubmit(evt) { evt.preventDefault(); this.$refs.addBookModal.hide(); let read=false; if(this.BookForm.read[0]) read=true; const payload={ del_id:"null", id:"null", title: this.BookForm.title, author: this.BookForm.author, read }; this.addBook(payload); this.initForm(); }, add_onReset(evt) { evt.preventDefault(); this.$refs.addBookModal.hide(); this.initForm(); }, }, created() { this.getBooks(); } }; </script>
Modify the back-end code (app.py) to add the identification and operation of POST requests:
··· @app.route('/',methods=['GET','POST','OPTIONS']) def all_books(): response_object = {'status':'success'} books = selectDataAll() if request.method == 'POST': post_data = request.get_json() print(post_data) books_id = post_data.get('id') del_id = post_data.get('del_id') title = post_data.get('title'), author = post_data.get('author'), read = post_data.get('read') insertData( title=title[0], author=author[0], read=read ) response_object['message'] = 'Book added!' else: response_object['books']=books return jsonify(response_object) ···
Do the same, write the update button click event and del event
Attached books Vue all codes:
<template> <div class="container" align="left"> <div class="row"> <div class="col-sm-10"> <h1>Books</h1> <hr /> <br /> <div> <b-alert variant="success" show>{{ message }}</b-alert> <br> </div> <br /> <button type="button" class="btn btn-success btn-sm" v-b-modal.book-add>Add Book</button> <br /> <br /> <table class="table table-hover"> <thead> <tr> <th scope="col">Title</th> <th scope="col">Author</th> <th scope="col">Read?</th> <th></th> </tr> </thead> <tbody> <tr v-for="(book, index) in books" :key="index"> <td>{{ book.title }}</td> <td>{{ book.author }}</td> <td> <span v-if="book.read">Yes</span> <span v-else>No</span> </td> <td> <div class="btn-group" role="group"> <button type="button" class="btn btn-warning" v-b-modal.book-up @click="book_update(index)">Update</button> <button type="button" class="btn btn-danger" @click="book_del(index)">Delete</button> </div> </td> </tr> </tbody> </table> </div> </div> <!-- ------------------------------------------------------Add-------------------------------------------------- --> <b-modal ref="addBookModal" id="book-add" title="Add a new book" hide-footer> <b-form @submit="add_onSubmit" @reset="add_onReset" class="w-100"> <b-form-group id="form-title-group" label="Title:" label-for="form-title-input"> <b-form-input id="form-title-input" type="text" v-model="BookForm.title" required placeholder="Enter title" ></b-form-input> </b-form-group> <b-form-group id="form-author-group" label="Author:" label-for="form-author-input"> <b-form-input id="form-author-input" type="text" v-model="BookForm.author" required placeholder="Enter author" ></b-form-input> </b-form-group> <b-form-group id="form-read-group"> <b-form-checkbox-group v-model="BookForm.read" id="form-checks"> <b-form-checkbox value="true">Read?</b-form-checkbox> </b-form-checkbox-group> </b-form-group> <b-button-group> <b-button type="submit" variant="primary">Submit</b-button> <b-button type="reset" variant="danger">Reset</b-button> </b-button-group> </b-form> </b-modal> <!-- ----------------------------------------------------Up date------------------------------------------------ --> <b-modal ref="upBookModal" id="book-up" title="update book" hide-footer> <b-form @submit="up_onSubmit" @reset="up_onReset" class="w-100"> <b-form-group id="form-title-group" label="Title:" label-for="form-title-input"> <b-form-input id="form-title-input" type="text" v-model="BookForm.title" required placeholder="Enter title" ></b-form-input> </b-form-group> <b-form-group id="form-author-group" label="Author:" label-for="form-author-input"> <b-form-input id="form-author-input" type="text" v-model="BookForm.author" required placeholder="Enter author" ></b-form-input> </b-form-group> <b-form-group id="form-read-group"> <b-form-checkbox-group v-model="BookForm.read" id="form-checks"> <b-form-checkbox value="true">Read?</b-form-checkbox> </b-form-checkbox-group> </b-form-group> <b-button-group> <b-button type="submit" variant="primary">Submit</b-button> <b-button type="reset" variant="danger">Reset</b-button> </b-button-group> </b-form> </b-modal> <!-- ------------------------------------------------------del-------------------------------------------------- --> </div> </template> <script> import axios from "axios"; import Alert from './Alert.vue' export default { data() { return { props: ['message'], books: [], BookForm: { delbook:"", id: "", title: "", author: "", read: [] }, message: '', }; }, commponents:{ alert:Alert, }, methods: { getBooks() { const path="http://127.0.0.1:5000"; axios .get(path) .then(res => { this.books=res.data.books; }) .catch(error => { console.error(error); }); }, initForm() { this.BookForm.delbook='null'; this.BookForm.id="null"; this.BookForm.title=""; this.BookForm.author=""; this.BookForm.read=[]; }, // --------------------------Add----------------------------- addBook(payload) { const path="http://127.0.0.1:5000"; axios .post(path, payload) .then(() => { this.getBooks(); this.message = 'Book added!' }) .catch(error => { console.log(error); this.getBooks(); }); }, add_onSubmit(evt) { evt.preventDefault(); this.$refs.addBookModal.hide(); let read=false; if(this.BookForm.read[0]) read=true; const payload={ del_id:"null", id:"null", title: this.BookForm.title, author: this.BookForm.author, read }; this.addBook(payload); this.initForm(); }, add_onReset(evt) { evt.preventDefault(); this.$refs.addBookModal.hide(); this.initForm(); }, // ------------------------up date----------------------- book_update:function(index){ this.BookForm.id=index+1 }, upBook(payload) { const path="http://127.0.0.1:5000"; axios .post(path, payload) .then(() => { this.getBooks(); this.message = 'Book update!' }) .catch(error => { console.log(error); this.getBooks(); }); }, up_onSubmit(evt) { evt.preventDefault(); this.$refs.upBookModal.hide(); let read=false; if(this.BookForm.read[0]) read=true; const payload={ id: this.BookForm.id, del_id: "null", title: this.BookForm.title, author: this.BookForm.author, read }; this.upBook(payload); this.initForm(); }, up_onReset(evt) { evt.preventDefault(); this.$refs.upBookModal.hide(); this.initForm(); }, // --------------------------del------------------------- book_del:function(index){ this.BookForm.delbook=index+1 let read=false; if(this.BookForm.read[0]) read=true; const payload={ id:"null", del_id: this.BookForm.delbook, title: this.BookForm.title, author: this.BookForm.author, read }; this.delBook(payload); this.initForm(); }, delBook(payload) { const path="http://127.0.0.1:5000"; axios .post(path, payload) .then(() => { this.getBooks(); this.message = 'Book del!' }) .catch(error => { console.log(error); this.getBooks(); }); }, }, created() { this.getBooks(); } }; </script>
Modify the back-end code and use the functions according to the rules:
from flask import Flask, jsonify, request, make_response from flask_sqlalchemy import SQLAlchemy from flask_cors import CORS app = Flask(__name__) @app.after_request def after(resp): resp = make_response(resp) resp.headers['Access-Control-Allow-Origin'] = '*' resp.headers['Access-Control-Allow-Methods'] = '*' resp.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type' resp.headers['Access-Control-Allow-Credentials'] = 'True' return resp app.config['DEBUG'] = True CORS(app, resources=r'/*', supports_credentials=True) # ------------------database---------------------------- app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.sqlite' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True db = SQLAlchemy(app) class Books(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(80), nullable=False) author = db.Column(db.String(120), nullable=False) read= db.Column(db.Boolean) db.create_all() # increase def insertData(title,author,read): book=Books(title=title,author=author,read=read) db.session.add_all([book]) db.session.commit() # check def selectDataAll(): book_list=[] books = Books.query.all() for s in books: dic = {} dic['id'] = s.id dic['title'] = s.title dic['author'] = s.author dic['read'] = s.read print(f'Id: {s.id} | Title: {s.title} | Author: {s.author} | Read: {s.read}') print('----') book_list.append(dic) return book_list # Delete def deleteData(id): book = Books.query.get(id) db.session.delete(book) db.session.commit() # change def updateData(id, title='', author='', read='', new_id=''): book = Books.query.get(id) if not title=='': book.title = title if not author == '': book.author = author if not read == '': book.read = read if not new_id == '': book.id=new_id db.session.commit() # ------------------database---end---------------------- @app.route('/',methods=['GET','POST','OPTIONS']) def all_books(): response_object = {'status':'success'} books = selectDataAll() if request.method == 'POST': post_data = request.get_json() print(post_data) books_id = post_data.get('id') del_id = post_data.get('del_id') if books_id == 'null' and del_id == 'null': title = post_data.get('title'), author = post_data.get('author'), read = post_data.get('read') insertData( title=title[0], author=author[0], read=read ) response_object['message'] = 'Book added!' elif (not books_id == 'null') and del_id == 'null': put_data = post_data books_id = put_data.get('id') title = put_data.get('title') author = put_data.get('author') read = put_data.get('read') updateData( id=books_id, title=title, author=author, read=read ) response_object['message'] = 'Book update!' else: deleteData(del_id) response_object['message'] = 'Book del!' else: response_object['books']=books books = selectDataAll() for i in range(len(books)): id=books[i]['id'] updateData(id=id,new_id=i+1) print(response_object) return jsonify(response_object) if __name__ == '__main__': app.run(port=5000,debug=True)
So far, the codeword is hard. Please leave a praise before you go. Thank you first!