修改后的Google App Engine示例

0 投票
3 回答
1345 浏览
提问于 2025-04-16 03:47

我拿了一个谷歌应用引擎的官方示例,这个示例是用来创建一个购物清单的。我对它进行了修改,让它创建两个表格(联系人和电话号码),而不是一个购物清单。

这样做是为了理解谷歌是如何处理两个表格和外键的(见下面的代码)。

在第47行之前,它能正常显示所有内容:

data = PhoneNumber(data=self.request.POST)
data2 = Contact(data2=self.request.POST)

但是,它似乎无法处理第二个“data2”对象,给我报了一个错误:

TypeError: init() 收到了一个意外的关键字参数 'data2'

这是为什么呢?我该怎么做才能让它正常工作呢?

谢谢你的时间。

import cgi

from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app

from google.appengine.ext.db import djangoforms

class Contact(db.Model):
    name = db.StringProperty()
    birth_day = db.DateProperty()
    address = db.PostalAddressProperty()

class PhoneNumber(db.Model):
    contact = db.ReferenceProperty(Contact,
                                   collection_name='phone_numbers')
    phone_type = db.StringProperty(
        choices=('home', 'work', 'fax', 'mobile', 'other'))
    number = db.PhoneNumberProperty()

class PhoneNumberForm(djangoforms.ModelForm):
    class Meta:
        model = PhoneNumber

class ContactForm(djangoforms.ModelForm):
    class Meta:
        model = Contact

class MainPage(webapp.RequestHandler):
    def get(self):
        self.response.out.write('<html><body>'
                                '<form method="POST" '
                                'action="/">'
                                '<table>')
        # This generates our PhoneNumber, Contact list form and writes it in the response
        self.response.out.write(PhoneNumberForm())
        self.response.out.write(ContactForm())
        self.response.out.write('</table>'
                                '<input type="submit">'
                                '</form></body></html>')
    def post(self):
        #print self.request
        #print self.request.POST
        data = PhoneNumber(data=self.request.POST)
        data2 = Contact(data2=self.request.POST)
        if data.is_valid():
            # Save the data, and redirect to the view page
            entity = data.save(commit=False)
            entity.added_by = users.get_current_user()
            entity.put()
            self.redirect('/items.html')
        if data2.is_valid():
            # Save the data, and redirect to the view page
            entity = data2.save(commit=False)
            entity.added_by = users.get_current_user()
            entity.put()
            self.redirect('/items.html')
        else:
            # Reprint the form
            self.response.out.write('<html><body>'
                                    '<form method="POST" '
                                    'action="/">'
                                    '<table>')
            self.response.out.write(data)
            self.response.out.write(data2)
            self.response.out.write('</table>'
                                    '<input type="submit">'
                                    '</form></body></html>')

class ItemPage(webapp.RequestHandler):
    def get(self):
        query = db.GqlQuery("SELECT * FROM PhoneNumber ORDER BY name")
        for item in query:
            self.response.out.write('<a href="/edit?id=%d">Edit</a> - ' %
                                    item.key().id())
            self.response.out.write("%s - Need to buy %d, cost $%0.2f each<br>" %
                                    (item.name, item.quantity, item.target_price))

class EditPage(webapp.RequestHandler):
    def get(self):
        id = int(self.request.get('id'))
        item = Item.get(db.Key.from_path('Item', id))
        self.response.out.write('<html><body>'
                                '<form method="POST" '
                                'action="/edit">'
                                '<table>')
        self.response.out.write(PhoneNumberForm(instance=PhoneNumber))
        self.response.out.write(ContactForm(instance=Contact))
        self.response.out.write('</table>'
                                '<input type="hidden" name="_id" value="%s">'
                                '<input type="submit">'
                                '</form></body></html>' % id)
    def post(self):
        id = int(self.request.get('_id'))
        PhoneNumber = PhoneNumber.get(db.Key.from_path('PhoneNumber', id))
        Contact = Contact.get(db.Key.from_path('Contact', id))
        data = PhoneNumberForm(data=self.request.POST)
        data2 = ContactForm(data2=self.request.POST)
        if data.is_valid():
            # Save the data, and redirect to the view page
            entity = data.save(commit=False)
            entity.added_by = users.get_current_user()
            entity.put()
            self.redirect('/items.html')
        if data2.is_valid():
            # Save the data, and redirect to the view page
            entity = data2.save(commit=False)
            entity.added_by = users.get_current_user()
            entity.put()
            self.redirect('/items.html')
        else:
            # Reprint the form
            self.response.out.write('<html><body>'
                                    '<form method="POST" '
                                    'action="/">'
                                    '<table>')
            self.response.out.write(data)
            self.response.out.write(data2)
            self.response.out.write('</table>'
                                    '<input type="submit">'
                                    '</form></body></html>')

def main():
    application = webapp.WSGIApplication(
                                         [('/', MainPage),
                                          ('/edit', EditPage),
                                          ('/items.html', ItemPage),
                                          ],
                                         debug=True)

    run_wsgi_app(application)
if __name__=="__main__":
    main()

3 个回答

1

这对我来说似乎有效。

我把

data = PhoneNumber(data=self.request.POST)
data2 = Contact(data=self.request.POST)

改成了

data = PhoneNumberForm(data=self.request.POST)
data2 = ContactForm(data=self.request.POST)

def post(self):
    #print self.request
    #print self.request.POST
    data = PhoneNumberForm(data=self.request.POST)
    data2 = ContactForm(data=self.request.POST)
    if data.is_valid():
        # Save the data, and redirect to the view page
        entity = data.save(commit=False)
        entity.added_by = users.get_current_user()
        entity.put()
        self.redirect('/items.html')
    if data2.is_valid():
        # Save the data, and redirect to the view page
        entity = data2.save(commit=False)
        entity.added_by = users.get_current_user()
        entity.put()
        self.redirect('/items.html')
    else:
        # Reprint the form
        self.response.out.write('<html><body>'
                                '<form method="POST" '
                                'action="/">'
                                '<table>')
        self.response.out.write(data)
        self.response.out.write(data2)
        self.response.out.write('</table>'
                                '<input type="submit">'
                                '</form></body></html>')
1

其实你可以稍微简化一下你的代码。

class Contact(db.Model):
    name = db.StringProperty()
    birth_day = db.DateProperty()
    address = db.PostalAddressProperty()
    added_by = db.UserProperty(auto_current_user_add=True)

class PhoneNumber(db.Model):
    contact = db.ReferenceProperty(Contact,
                                   collection_name='phone_numbers')
    phone_type = db.StringProperty(
        choices=('home', 'work', 'fax', 'mobile', 'other'))
    number = db.PhoneNumberProperty()
    added_by = db.UserProperty(auto_current_user_add=True)

在表单的保存方法里,你不需要手动添加当前用户,应用引擎可以自动帮你处理这个。

在你的 def post(self): 函数里,不应该用 data2 参数来创建表单,这样是不对的。一般我会这样做:

def post(self):
    form1 =  PhoneNumberForm(self.request.POST or None)
    form2 = Contact(self.request.POST or None)
    if form1.is_valid() and form2.is_valid():
        form1.save()
        form2.save()
    else:
        # re-display page....

在你提问的地方,有两个地方错误地把 'data2' 传给了表单的构造函数(MainPage 类和 EditPage 类),记得把这两个地方都改正过来。

1

我没有用过Django的表单,但我猜大概是这样的:

def post(self): 
    #print self.request 
    #print self.request.POST 
    data = PhoneNumberForm(data=self.request.POST) 
    data2 = ContactForm(data=self.request.POST) 
    if data.is_valid() and data2.is_valid(): 
        # Save the data, and redirect to the view page 
        entity = data.save(commit=False) 
        entity.added_by = users.get_current_user() 
        entity.put() 
        entity = data2.save(commit=False) 
        entity.added_by = users.get_current_user() 
        entity.put() 
        self.redirect('/items.html') 
    else: 
        # Reprint the form 
        self.response.out.write('<html><body>' 
                                '<form method="POST" ' 
                                'action="/">' 
                                '<table>') 
        self.response.out.write(data) 
        self.response.out.write(data2) 
        self.response.out.write('</table>' 
                                '<input type="submit">' 
                                '</form></body></html>') 

你需要从self.request.POST创建的是表单类,而不是模型类。

这些表单类有一个叫做data的参数,而不是data2。

撰写回答