0

我正在探索使用 CherryPy 作为后端和 emberjs 作为管理书籍列表的简单 Web 应用程序的前端。Cherrypy 只是根据索引请求提供车把模板:

import os
import cherrypy
from google.appengine.api import users
from google.appengine.ext import ndb

class Root:

    def __init__(self):
        # book REST API
        self.books = BookAPI()

    @cherrypy.expose
    def index(self):
        return open(os.path.join(template_env, 'index.hbs'))

我使用 BooksAPI 和 Books 类作为 RESTfull API,使用 Google 数据存储来存储图书对象(我现在只存储 isbn)。

class BookAPI():
    exposed=True

    @cherrypy.tools.json_out()
    def GET(self, isbn=None):

        # get the current user
        user = users.get_current_user()

        if(isbn is None):

            # query all books current user
            ancestor_key = ndb.Key("Library", str(user.user_id()))
            books = Book.query_books(ancestor_key).fetch(20)

            # convert to JSON list of books
            book_list = []
            for index, b in enumerate(books):
                book_list.append({'id': index, 'isbn': b.isbn})
            result = {
                "books": book_list
            }

        return result

    def POST(self, isbn):

        # get the current user
        user = users.get_current_user()

        # create book and save in data storage
        parent_key = ndb.Key('Library', user.user_id())
        book = Book(parent=parent_key, isbn=isbn)
        book.put()

    ...

class Book(ndb.Model):

    isbn = ndb.StringProperty()

    @classmethod
    def query_books(cls, ancestor_key):
        return cls.query(ancestor=ancestor_key)

对于 emberjs 客户端,我使用 RESTAdapter:

window.Books = Ember.Application.create();
Books.ApplicationAdapter = DS.RESTAdapter.extend();

我的 emberjs 图书模型定义如下:

Books.Book = DS.Model.extend({
  isbn: DS.attr('string'),
});

我添加了以下书籍控制器:

Books.BookController = Ember.ObjectController.extend({
  actions: {
    removeBook: function() {
      var book = this.get('model');
      book.deleteRecord();
      book.save();
    }
  }
});

Books.BooksController = Ember.ArrayController.extend({
  actions: {
    createBook: function() {
      // get book isbn
      var isbn = this.get('newIsbn');
      if(!isbn.trim()) { return; }
      // create new book model
      var book = this.store.createRecord('book', {
        isbn: isbn,
      });
      // clear the 'new book' text field
      this.set('newIsbn', '');
      // Save model
      book.save();
    }
  }
});

最后是以下路线:

Books.Router.map(function () {
  this.resource('books', { path: '/' });
});

Books.BooksRoute = Ember.Route.extend({
  model: function() {
    return this.store.find('book');
  }
});

使用 FixedAdapter 添加和删除书籍有效,然后我切换到 RESTAdapter。

GET 方法有效。Emberjs 自动调用 GET 方法,成功获取到 index.hbs 模板中显示的 JSON 格式的书籍列表。

但是,emberjs 以我没想到的方式调用 POST 方法。ember 似乎发送了一个空的 POST,而没有将 isbn 添加为 POST 数据。因为当我从cherrypy POST 函数中删除isbn 关键字参数时,该函数会被调用。不过,我需要 isbn 来创建 book 对象。

我可能在这里忘记了一些明显的东西,但我不知道是什么。有谁知道我忘记了什么或做错了什么?谢谢。

巴斯蒂安

4

1 回答 1

1

为了保存新记录,Ember 发送保存在帖子正文中的对象的 json 表示...

在你的情况下应该是

book:{isbn:[the isbn value]}

所以没有isbn参数

你能在你的帖子功能上用这个测试吗

def POST(self):

    # get the current user
    user = users.get_current_user()
    cl = cherrypy.request.headers['Content-Length']
    rawbody = cherrypy.request.body.read(int(cl))
    body = simplejson.loads(rawbody)
    bookFromPost = body.book
    # create book and save in data storage
    parent_key = ndb.Key('Library', user.user_id())
    book = Book(parent=parent_key, isbn=bookFromPost.isbn)
    book.put()

您应该返回一个 201 创建的 HTTP 代码,其中包含分配 id 的书的 json 表示

book:{id:[the new id],isbn:[the isbn value]}
于 2013-10-21T13:10:55.640 回答