2016-02-23 82 views
1

我正在開發一個Flask應用來管理一個庫。我遇到的其中一個問題與添加新書有關。在很多情況下,有「作者碰撞」;基本上是一本以「約翰·史密斯」爲作者的書,然後另一本以「約翰·史密斯」爲作者的書被添加到數據庫中。第一本書的作者「約翰史密斯」是否與第二本書的作者一樣是「約翰史密斯」?交互式Flask提示

我對這個問題的解決方案是在模態對話框中向用戶呈現「作者衝突」,作者姓名的形式,以及當前在數據庫中歸屬於作者的書籍列表。問題是我不知道如何實現這一點。我的第一個想法是重定向到另一個頁面,用戶可以在新頁面中回答這些問題。問題是這需要一些看似不可靠的設計,例如保存狀態數據(用戶已經輸入的書籍元數據的其餘部分)。

我在想我應該做的是在LoanBook(MethodView)中實現某種「Post方法」,產生一系列的模式對話框(每個作者碰撞一個,因爲書可以有多個作者),僅當每個作者碰撞已經解決了'是'或'否'。

理想情況下,我希望能夠停止Post方法(在標記爲# ??? yield ???的位置),等待用戶的響應,然後根據響應運行代碼。如有必要,重複。我不知道是否有一些Flask擴展或方法可以實現,或者甚至可能。我應該做另一種方法嗎?有沒有人有什麼建議?

class LoanBook(MethodView): 
    decorators = [login_required] 
    form = None 

    def __init__(self): 
     self.book = None 
     self.form = self.prep_form() 

    @permissions_required(Permission.CHECK_OUT_BOOK) 
    def get(self): 
     return render_template("library/loan_book.html", form=self.form) 

    @permissions_required(Permission.CHECK_OUT_BOOK) 
    def post(self):   
     if self.form.validate_on_submit(): 
      if self.form.fill_ISBN.data: 
       # User has hit the fill data from ISBN button 
       pass 
      else: 
       try: 
        self.__make_book__() 
        db.session.add(self.book) 
        db.session.commit() 
       except InvalidRequestError: 
        db.session.rollback() 
        db.session.flush() 
        flash(FlashMessage.not_saved, FlashMessage.failure) 
       else: 
        auths = None 
        if len(loanedBook.authors) > 1: 
         auths = oxford_commatize(
           [a.full_name() for a in loanedBook.authors] 
          ) 
        else: 
         auths = loanedBook.authors[0].full_name() 
        flash(
         FlashMessage.saved.format(loanedBook.title, auths), 
         FlashMessage.failure 
        ) 
       return redirect(url_for("library.main")) 
     elif self.form.author_collisions: 
      uri_auth = [] 
      for auth in self.form.author_collisions: 
       # ??? yield ??? 
      self.__make_book__() 
      db.session.add(self.book) 
      db.session.commit() 
     else: 
      flash_errors(self.form) 
     return render_template("library/loan_book.html", form=self.form) 

回答

0

這不能單獨在Flask中完成,除非如你所說,你會得到一點RESTless ......但一種方法是預先保存數據並返回一個頁面,首次碰撞時帶有一個標識符,用於記錄你正在創建過程中。我會在一些AJAX或websocket連接中加載碰撞,當輸入作者的名字時,會在頁面的另一個區域(div)中加載碰撞 - 如果你對完全無狀態感興趣:)

我會使用websockets(實際上,socket.io是websockets的更多功能包裝器),並在用戶輸入作者姓名時在請求中觸發JavaScript事件。然後可以使用websocket的JSON響應來填充頁面上的一個區域,並且可以在那裏選擇任何匹配的結果。在服務器端使用flask-socketio;在文檔中有一個JavaScript示例,應該讓你在瀏覽器端開始。

燒瓶SocketIO的文檔可以在這裏找到: http://flask-socketio.readthedocs.org/en/latest/

這是表示在本基礎的優秀的視頻,與用於代碼回購: https://www.youtube.com/watch?v=L5YQbNrFfyw

+0

的問題是,碰撞AREN直到表單提交後才能檢測到。我對AJAX不太熟悉,如果給出一個與作者匹配的書籍的JSON對象,它可以在輸入時檢測到衝突嗎?你會怎麼做呢? – BrotherJack

+0

我會使用websockets(實際上,socket.io是websockets的一個更實用的包裝器),當用戶輸入作者姓名時,會在請求中觸發JavaScript事件。然後可以使用websocket的JSON響應來填充頁面上的一個區域,並且可以在那裏選擇任何匹配的結果。在服務器端使用flask-socketio;在文檔中有一個JavaScript示例,應該讓你在瀏覽器端開始。 –

+0

這聽起來像個好主意。我會認爲這是一個答案,如果你只是將以前的評論放入你的答案,我會選擇它。如果這不被認爲是「太寬泛」:| – BrotherJack

0

嘗試在服務器端的連續操作之間獲得用戶干預,你不會取得太大的成功。一個API可以將這些衝突檢測爲初始頁面的異步組件,以便用戶在提交到此端點之前解決它們可能是最好的。