修改后的Google App Engine示例
我拿了一个谷歌应用引擎的官方示例,这个示例是用来创建一个购物清单的。我对它进行了修改,让它创建两个表格(联系人和电话号码),而不是一个购物清单。
这样做是为了理解谷歌是如何处理两个表格和外键的(见下面的代码)。
在第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。