我正在尝试更新数据库中的餐馆名称并收到错误。
网站打印出所有餐馆名称,然后用户在餐厅下面选择“编辑”按钮,他们想要更改名称。在转到另一个页面之前,我使用餐馆名称查询数据库,检索id,然后我构建将PK插入URL。
然后我分解URL并在POST方法中检索PK并尝试使用用户选择的名称更新数据库名称。
以下是代码和当前错误:
webserver.py
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from database_setup import Restaurant, Base, MenuItem
import cgi
class webServerHandler(BaseHTTPRequestHandler):
def do_GET(self):
try:
if self.path.endswith("/hello"):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
output = ""
output += "<html><body>Hello!"
output += '''<form method='POST' enctype='multipart/form-data' action='/hello'><h2>What would you like me to say?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
output +="</body></html>"
self.wfile.write(output)
print output
return
if self.path.endswith("/hola"):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
output = ""
output += "<html><body> ¡ Hola ! <a href = '/hello'> Back to Hello </a></body></html>"
output += '''<form method='POST' enctype='multipart/form-data' action='/hello'><h2>What would you like me to say?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
output +="</body></html>"
self.wfile.write(output)
print message
return
if self.path.endswith("/restaurants"):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind = engine)
session = DBSession()
items = session.query(Restaurant).all()
output = "<html><body> <br> Printing all Restaurants ! </br>"
for item in items:
output += "<br>" + item.name + "</br>"
output += "<br> <a href = '/" + str(item.id) + "/rename'> Edit </a></br>"
output += "<br> <a href = '/" + str(item.id) + "/delete'> Delete </a></br>"
output += "<br> <a href = '/new'> Create new restaurant </a></br>"
output += "</body></html>"
self.wfile.write(output)
print output
return
if self.path.endswith("/new"):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
output = ""
output += "<html><body>Make a New Restaurant"
output += '''<form method='POST' enctype='multipart/form-data' action='/new'><h2>Name of new restaurant ?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
output +="</body></html>"
self.wfile.write(output)
print output
return
if self.path.endswith("/rename"):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
x = self.path
x = x[:-7]
x = x[1:]
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind = engine)
session = DBSession()
items = session.query(Restaurant).filter_by(id = x)
output = ""
for item in items:
output += "<html><body><h2>" + item.name + "</h2>"
output += '''<form method='POST' enctype='multipart/form-data' action='/rename'><h2>New name of restaurant ?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
output +="</body></html>"
self.wfile.write(output)
print output
print x
return
except IOError:
self.send_error(404, 'File Not Found: %s' % self.path)
def do_POST(self):
if self.path.endswith("/new"):
self.send_response(301)
self.send_header('Content-type','text/html')
self.end_headers()
ctype, pdict = cgi.parse_header(
self.headers.getheader('content-type'))
if ctype == 'multipart/form-data':
fields = cgi.parse_multipart(self.rfile, pdict)
messagecontent = fields.get('message')
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind = engine)
session = DBSession()
myrest = Restaurant(name = messagecontent[0])
session.add(myrest)
session.commit()
output = "Restaurant added"
output +="<br><a href = '/restaurants'> Back to restaurants </a></br>"
output +="</body></html>"
self.wfile.write(output)
print output
if self.path.endswith("/rename"):
self.send_response(301)
self.send_header('Content-type','text/html')
self.end_headers()
y = self.path
y = y[:-7]
y = y[1:]
print y
ctype, pdict = cgi.parse_header(
self.headers.getheader('content-type'))
if ctype == 'multipart/form-data':
fields = cgi.parse_multipart(self.rfile, pdict)
messagecontent = fields.get('message')
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind = engine)
session = DBSession()
findrest = session.query(Restaurant).filter_by(id = y).one()
findrest.name = messagecontent[0]
session.add(findrest)
session.commit()
output = "Restaurant " + messagecontent[0] + " added"
output +="<br><a href = '/restaurants'> Back to restaurants </a></br>"
output +="</body></html>"
self.wfile.write(output)
print output
def main():
try:
port = 8080
server = HTTPServer(('', port), webServerHandler)
print "Web Server running on port %s" % port
server.serve_forever()
except KeyboardInterrupt:
print " ^C entered, stopping web server...."
server.socket.close()
if __name__ == '__main__':
main()
database_setup.py
import os
import sys
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine
Base = declarative_base()
class Restaurant(Base):
__tablename__ = 'restaurant'
id = Column(Integer, primary_key=True)
name = Column(String(250), nullable=False)
class MenuItem(Base):
__tablename__ = 'menu_item'
name = Column(String(80), nullable=False)
id = Column(Integer, primary_key=True)
description = Column(String(250))
price = Column(String(8))
course = Column(String(250))
restaurant_id = Column(Integer, ForeignKey('restaurant.id'))
restaurant = relationship(Restaurant)
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.create_all(engine)
来自网络服务器的错误
1
10.0.2.2 - - [30/Mar/2016 10:10:46] "POST /rename HTTP/1.1" 301 -
----------------------------------------
Exception happened during processing of request from ('10.0.2.2', 59743)
Traceback (most recent call last):
File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
self.process_request(request, client_address)
File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request
self.finish_request(request, client_address)
File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python2.7/SocketServer.py", line 649, in __init__
self.handle()
File "/usr/lib/python2.7/BaseHTTPServer.py", line 340, in handle
self.handle_one_request()
File "/usr/lib/python2.7/BaseHTTPServer.py", line 328, in handle_one_request
method()
File "webserver.py", line 132, in do_POST
findrest = session.query(Restaurant).filter_by(id = int(y)).one()
ValueError: invalid literal for int() with base 10: ''
----------------------------------------
您可以看到Y在上面的
中打印为1答案 0 :(得分:0)
您遇到了命名空间问题。
do_GET()
方法中定义的变量在do_POST()
中不可见,并且完全正常。
如果您想在两者之间分享内容,请使用x = self.path
替换self.x = self.path
来使用类属性。
因此,如果您想在do_POST
中访问它,findrest = session.query(Restaurant).filter_by(id = self.x).one()
应该有效。
最后的注意事项:如果您只是在玩BaseHTTPRequestHandler来理解它很好。否则,你可以看看Flask或Django!
答案 1 :(得分:0)
解决!解决方案代码如下:
webserver.py
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from database_setup import Restaurant, Base, MenuItem
import cgi
class webServerHandler(BaseHTTPRequestHandler):
def do_GET(self):
try:
if self.path.endswith("/hello"):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
output = ""
output += "<html><body>Hello!"
output += '''<form method='POST' enctype='multipart/form-data' action='/hello'><h2>What would you like me to say?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
output +="</body></html>"
self.wfile.write(output)
print output
return
if self.path.endswith("/hola"):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
output = ""
output += "<html><body> ¡ Hola ! <a href = '/hello'> Back to Hello </a></body></html>"
output += '''<form method='POST' enctype='multipart/form-data' action='/hello'><h2>What would you like me to say?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
output +="</body></html>"
self.wfile.write(output)
print message
return
if self.path.endswith("/restaurants"):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind = engine)
session = DBSession()
items = session.query(Restaurant).all()
output = "<html><body> <br> Printing all Restaurants ! </br>"
for item in items:
output += "<br>" + item.name + "</br>"
output += "<br> <a href = '/" + str(item.id) + "/rename'> Edit </a></br>"
output += "<br> <a href = '/" + str(item.id) + "/delete'> Delete </a></br>"
output += "<br> <a href = '/new'> Create new restaurant </a></br>"
output += "</body></html>"
self.wfile.write(output)
print output
return
if self.path.endswith("/new"):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
output = ""
output += "<html><body>Make a New Restaurant"
output += '''<form method='POST' enctype='multipart/form-data' action='/new'><h2>Name of new restaurant ?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
output +="</body></html>"
self.wfile.write(output)
print output
return
if self.path.endswith("/rename"):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind = engine)
session = DBSession()
x = self.path
x = x[:-7]
x = x[1:]
item = session.query(Restaurant).filter_by(id = x).one()
output = ""
output += "<html><body><h2>" + item.name + "</h2>"
output += """<form method='POST' enctype='multipart/form-data' action='/""" + str(item.id) + """/rename'><h2>New name of restaurant ?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>"""
output +="</body></html>"
self.wfile.write(output)
print output
return
except IOError:
self.send_error(404, 'File Not Found: %s' % self.path)
def do_POST(self):
if self.path.endswith("/new"):
self.send_response(301)
self.send_header('Content-type','text/html')
self.end_headers()
ctype, pdict = cgi.parse_header(
self.headers.getheader('content-type'))
if ctype == 'multipart/form-data':
fields = cgi.parse_multipart(self.rfile, pdict)
messagecontent = fields.get('message')
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind = engine)
session = DBSession()
myrest = Restaurant(name = messagecontent[0])
session.add(myrest)
session.commit()
output = "Restaurant added"
output +="<br><a href = '/restaurants'> Back to restaurants </a></br>"
output +="</body></html>"
self.wfile.write(output)
print output
if self.path.endswith("/rename"):
self.send_response(301)
self.send_header('Content-type','text/html')
self.end_headers()
y = self.path
y = y[:-7]
y = y[1:]
ctype, pdict = cgi.parse_header(
self.headers.getheader('content-type'))
if ctype == 'multipart/form-data':
fields = cgi.parse_multipart(self.rfile, pdict)
messagecontent = fields.get('message')
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind = engine)
session = DBSession()
findrest = session.query(Restaurant).filter_by(id = y).one()
findrest.name = messagecontent[0]
session.add(findrest)
session.commit()
output = "Restaurant " + messagecontent[0] + " renamed"
output +="<br><a href = '/restaurants'> Back to restaurants </a></br>"
output +="</body></html>"
self.wfile.write(output)
print output
def main():
try:
port = 8080
server = HTTPServer(('', port), webServerHandler)
print "Web Server running on port %s" % port
server.serve_forever()
except KeyboardInterrupt:
print " ^C entered, stopping web server...."
server.socket.close()
if __name__ == '__main__':
main()