前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用Flask和Vue.js开发一个单页面应用程序(四)

使用Flask和Vue.js开发一个单页面应用程序(四)

作者头像
TalkPython
发布2019-05-24 16:44:41
1.5K1
发布2019-05-24 16:44:41
举报
文章被收录于专栏:TalkPythonTalkPython

点击蓝字关注△ 回复“1024”领取福利大礼包

接上一次,继续分享,这是该系列的最后一篇文章。今天继续完成更新图书和删除图书的前后端功能。

更新图书服务程序

更新图书功能,使用PUT请求来完成。对于更新,我们需要使用唯一的标识符,因为我们不能依赖于标题是唯一的。我们可以使用Python标准库中的uuid。作为每一本图书的唯一ID。

首先更新一下app.py中的BOOKS数据,具体如下:

代码语言:javascript
复制
BOOKS = [
    {
        'id': uuid.uuid4().hex,
        'title': 'On the Road',
        'author': 'Jack Kerouac',
        'read': True
    },
    {
        'id': uuid.uuid4().hex,
        'title': 'Harry Potter and the Philosopher\'s Stone',
        'author': 'J. K. Rowling',
        'read': False
    },
    {
        'id': uuid.uuid4().hex,
        'title': 'Green Eggs and Ham',
        'author': 'Dr. Seuss',
        'read': True
    }
]

不要忘记,需要导入uuid。

代码语言:javascript
复制
import uuid

重构all_books方法,为添加新书,增加唯一id。

代码语言:javascript
复制
@app.route('/books', methods=['GET', 'POST'])
def all_books():
    response_object = {'status': 'success'}
    if request.method == 'POST':
        post_data = request.get_json()
        BOOKS.append({
            'id': uuid.uuid4().hex,
            'title': post_data.get('title'),
            'author': post_data.get('author'),
            'read': post_data.get('read')
        })
        response_object['message'] = 'Book added!'
    else:
        response_object['books'] = BOOKS
    return jsonify(response_object)

添加一个的路由,用于完成PUT请求:

代码语言:javascript
复制
@app.route('/books/<book_id>', methods=['PUT'])
def single_book(book_id):
    response_object = {'status': 'success'}
    if request.method == 'PUT':
        post_data = request.get_json()
        remove_book(book_id)
        BOOKS.append({
            'id': uuid.uuid4().hex,
            'title': post_data.get('title'),
            'author': post_data.get('author'),
            'read': post_data.get('read')
        })
        response_object['message'] = 'Book updated!'
    return jsonify(response_object)

需要添加一个辅助方法,来完成图书的更新:

代码语言:javascript
复制
def remove_book(book_id):
    for book in BOOKS:
        if book['id'] == book_id:
            BOOKS.remove(book)
            return True
    return False
更新图书前端程序

首先,添加一个新的模态到模板,像下面这样:

代码语言:javascript
复制
<b-modal ref="editBookModal"
         id="book-update-modal"
         title="Update"
         hide-footer>
  <b-form @submit="onSubmitUpdate" @reset="onResetUpdate" class="w-100">
  <b-form-group id="form-title-edit-group"
                label="Title:"
                label-for="form-title-edit-input">
      <b-form-input id="form-title-edit-input"
                    type="text"
                    v-model="editForm.title"
                    required
                    placeholder="Enter title">
      </b-form-input>
    </b-form-group>
    <b-form-group id="form-author-edit-group"
                  label="Author:"
                  label-for="form-author-edit-input">
        <b-form-input id="form-author-edit-input"
                      type="text"
                      v-model="editForm.author"
                      required
                      placeholder="Enter author">
        </b-form-input>
      </b-form-group>
    <b-form-group id="form-read-edit-group">
      <b-form-checkbox-group v-model="editForm.read" id="form-checks">
        <b-form-checkbox value="true">Read?</b-form-checkbox>
      </b-form-checkbox-group>
    </b-form-group>
    <b-button type="submit" variant="primary">Update</b-button>
    <b-button type="reset" variant="danger">Cancel</b-button>
  </b-form>
</b-modal>

添加JavaScript脚本部分,添加更新图书表单数据:

代码语言:javascript
复制
editForm: {
  id: '',
  title: '',
  author: '',
  read: [],
},

为Update按钮绑定点击事件:

代码语言:javascript
复制
<button
        type="button"
        class="btn btn-warning btn-sm"
        v-b-modal.book-update-modal
        @click="editBook(book)">
    Update
</button>

添加一个新方法来更新editForm中的值:

代码语言:javascript
复制
editBook(book) {
  this.editForm = book;
},

然后,添加一个方法来处理表单提交:

代码语言:javascript
复制
onSubmitUpdate(evt) {
  evt.preventDefault();
  this.$refs.editBookModal.hide();
  let read = false;
  if (this.editForm.read[0]) read = true;
  const payload = {
    title: this.editForm.title,
    author: this.editForm.author,
    read,
  };
  this.updateBook(payload, this.editForm.id);
},

调用后端的api接口:

代码语言:javascript
复制
updateBook(payload, bookID) {
  const path = `http://localhost:5000/books/${bookID}`;
  axios.put(path, payload)
    .then(() => {
      this.getBooks();
      this.message = 'Book updated!';
      this.showMessage = true;
    })
    .catch((error) => {
      // eslint-disable-next-line
      console.error(error);
      this.getBooks();
    });
},

绑定取消按钮事件:

代码语言:javascript
复制
onResetUpdate(evt) {
  evt.preventDefault();
  this.$refs.editBookModal.hide();
  this.initForm();
  this.getBooks(); // why?
},

更新initFrom:

代码语言:javascript
复制
initForm() {
  this.addBookForm.title = '';
  this.addBookForm.author = '';
  this.addBookForm.read = [];
  this.editForm.id = '';
  this.editForm.title = '';
  this.editForm.author = '';
  this.editForm.read = [];
},

一切搞定之后,运行前后端程序,试试效果吧。点击Update按钮,应该会是下面这样

删除图书后端程序

首先在single_book方法中,添加删除图书的方法:

代码语言:javascript
复制
@app.route('/books/<book_id>', methods=['PUT', 'DELETE'])
def single_book(book_id):
    response_object = {'status': 'success'}
    if request.method == 'PUT':
        post_data = request.get_json()
        remove_book(book_id)
        BOOKS.append({
            'id': uuid.uuid4().hex,
            'title': post_data.get('title'),
            'author': post_data.get('author'),
            'read': post_data.get('read')
        })
        response_object['message'] = 'Book updated!'
    if request.method == 'DELETE':
        remove_book(book_id)
        response_object['message'] = 'Book removed!'
    return jsonify(response_object)
删除图书前端程序

首先在Books.vue组件中,给Delete按钮,绑定一个click事件。

代码语言:javascript
复制
<button
        type="button"
        class="btn btn-danger btn-sm"
        @click="onDeleteBook(book)">
    Delete
</button>

然后再添加处理按钮点击的方法,然后删除图书:

代码语言:javascript
复制
removeBook(bookID) {
  const path = `http://localhost:5000/books/${bookID}`;
  axios.delete(path)
    .then(() => {
      this.getBooks();
      this.message = 'Book removed!';
      this.showMessage = true;
    })
    .catch((error) => {
      // eslint-disable-next-line
      console.error(error);
      this.getBooks();
    });
},
onDeleteBook(book) {
  this.removeBook(book.id);
},

现在,当用户单击delete按钮时,onDeleteBook方法被触发,而onDeleteBook方法又触发removeBook方法。此方法将DELETE请求发送到后端。当响应返回时,将显示警告消息并运行getBooks。

总结

本系列文章主要介绍了使用Vue和Flask设置CRUD应用程序的基础知识。

您可以公众号回复关键词flaskvue获取完整源代码。感谢你的阅读。

如果觉得内容还不错,分享给更多朋友,一起提升编程技能。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 TalkPython 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 更新图书服务程序
  • 更新图书前端程序
  • 删除图书后端程序
  • 删除图书前端程序
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档