Reputation: 18271
I took an official example of Google App Engine, that creates a Shoppinglist, and modified it so it would:
Create two tables (contact and Phonenumber) instead of one Shoppinglist. This is to understand how google deals with two tables and the Foreignkey (see code below).
It displays everything until line 47:
data = PhoneNumber(data=self.request.POST) data2 = Contact(data2=self.request.POST)
Somehow it cant deal with the second "data2" object and gives me and error:
TypeError: init() got an unexpected keyword argument 'data2'
Why? What can I do to make it work?
Thanks for the time.
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()
Upvotes: 0
Views: 1349
Reputation: 11
This seemed to work for me.
Changed
data = PhoneNumber(data=self.request.POST)
data2 = Contact(data=self.request.POST)
To
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>')
Upvotes: 1
Reputation: 4286
You could actually simplify your code a bit.
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)
You don't need to add the current user in the form's save method, you can have appengine do it automatically.
In your def post(self): function, you shouldn't be instantiating the form with a data2 argument, that's invalid. I generally do something like this:
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....
There are two spots in your question where you are incorrectly passing 'data2' to the form's constructor (MainPage class and EditPage class), be sure to correct them both.
Upvotes: 1
Reputation: 17624
I haven't used Django forms, but my guess would be something like this:
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>')
It is the form classes not the model classes which you need to create from self.request.POST.
These have an argument called data, not data2.
Upvotes: 1