我目前正在通过阅读《Head First Python 2nd Edition》这本书来学习Python,它确实很有帮助,而且写得很好,但我认为它有点过时(因为它是在2016年12月16日发布的,我认为从那时起各种事情都发生了变化)。
问题是:我刚刚完成了webapp * vsearch4web.py * 的编写(目前为止我必须完成的工作),它看起来如下所示:
from flask import Flask, render_template, request, escape
from vsearch import search4letters
from DBcm import UseDatabase
app = Flask(__name__)
app.config['dbconfig'] = {'host': '127.0.0.1',
'user': 'vsearch',
'password': 'vsearchpasswd',
'database': 'vsearchlogDB', }
def log_request(req: 'flask_request', res: str) -> None:
"""Log details of the web request and the results"""
with UseDatabase(app.config['dbconfig']) as cursor:
_SQL = """insert into log
(phrase, letters, ip, browser_string, results)
values
(%s, %s, %s, %s, %s)"""
cursor.execute(_SQL, (req.form['phrase'],
req.form['letters'],
req.remote_addr,
req.user_agent.browser,
res, ))
@app.route('/search4', methods=['POST'])
def do_search() -> 'html':
phrase = request.form['phrase']
letters = request.form['letters']
title = 'Here are your results:'
results = ''.join(search4letters(phrase, letters))
log_request(request, results)
return render_template('results.html',
the_title=title,
the_phrase=phrase,
the_letters=letters,
the_results=results,)
@app.route('/')
@app.route('/entry')
def entry_page() -> 'html':
return render_template('entry.html',
the_title='Welcome to search4letters on the web!')
@app.route('/viewlog')
def view_the_log() -> 'html':
with UseDatabase(app.config['dbconfig']) as cursor:
_SQL = """Select phrase, letters, ip, browser_string, results
from log"""
cursor.execute(_SQL)
contents = cursor.fetchall()
titles = ('Phrase', 'Letters', 'Remote_addr', 'User_agent', 'Results')
return render_template('viewlog.html',
the_title='View Log',
the_row_titles=titles,
the_data=contents,)
if __name__ == '__main__':
app.run(debug=True)
这是我在代码中使用的类:
import mysql.connector
class UseDatabase:
def __init__(self, config: dict) -> None:
self.configuration = config
def __enter__(self) -> 'cursor':
self.conn = mysql.connector.connect(**self.configuration)
self.cursor = self.conn.cursor()
return self.cursor
def __exit__(self, exc_type, exc_value, exc_trace) -> None:
self.conn.commit()
self.cursor.close()
self.conn.close()
然后,我在MySQL控制台中创建了数据库**"vsearchlogDB",之后(以用户"vsearch"的身份登录),我创建了表"log"**(输入的内容与书中所写的完全相同,即使生成的表略有不同,这就是为什么我之前说这本书可能有点过时):
(This是书中显示的表格):
现在,当我在本地运行我的webapp并试用它时,出现了以下错误:
mysql.connector.errors.IntegrityError: 1048(23000):列'browser_string'不能为空
有人能解释一下为什么代码不能提取browser_string的值吗?
我试着从头开始重新创建表,并将browser_string列置为空,事实上browser_string列(在/viewlog页面中)总是显示 * None *(尽管我认为这是一个无用的测试,因为我不知道如何使用MySQL),但它不应该是这样的,有人能解释一下吗?
这里我还添加了网页应用程序的(所有)页面的HTML和CSS代码(抱歉所有的代码,但我真的不知道问题出在哪里):
base.html:
<!doctype html>
<html>
<head>
<title>{{ the_title }}</title>
<link rel="stylesheet" href="static/hf.css" />
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
entry.html:
{% extends 'base.html' %}
{% block body %}
<h2>{{ the_title }}</h2>
<form method='POST' action='/search4'>
<table>
<p>Use this form to submit a search request:</p>
<tr><td>Phrase:</td><td><input name='phrase' type='TEXT' width='60'></td></tr>
<tr><td>Letters:</td><td><input name='letters' type='TEXT' value='aeiou'></td></tr>
</table>
<p>When you're ready, click this button:</p>
<p><input value="Do it!" type="submit"></p>
</form>
{% endblock %}
results.html:
{% extends 'base.html' %}
{% block body %}
<h2>{{ the_title }}</h2>
<p>You submitted the following data:</p>
<table>
<tr><td>Phrase:</td><td>{{ the_phrase }}</td></tr>
<tr><td>Letters:</td><td>{{ the_letters }}</td></tr>
</table>
<p>When "{{ the_phrase }}" is searched for "{{ the_letters }}", the following
results are returned:</p>
<h3>{{ the_results }}</h3>
{% endblock %}
viewlog.html:
{% extends 'base.html' %}
{% block body %}
<h2>{{ the_title }}</h2>
<table>
<tr>
{% for row_title in the_row_titles %}
<th>{{row_title}}</th>
{% endfor %}
</tr>
{% for log_row in the_data %}
<tr>
{% for item in log_row %}
<td>{{item}}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
{% endblock %}
hf.css:
body {
font-family: Verdana, Geneva, Arial, sans-serif;
font-size: medium;
background-color: tan;
margin-top: 5%;
margin-bottom: 5%;
margin-left: 10%;
margin-right: 10%;
border: 1px dotted gray;
padding: 10px 10px 10px 10px;
}
a {
text-decoration: none;
font-weight: 600;
}
a:hover {
text-decoration: underline;
}
a img {
border: 0;
}
h2 {
font-size: 150%;
}
table {
margin-left: 20px;
margin-right: 20px;
caption-side: bottom;
border-collapse: collapse;
}
td, th {
padding: 5px;
text-align: left;
}
.copyright {
font-size: 75%;
font-style: italic;
}
.slogan {
font-size: 75%;
font-style: italic;
}
.confirmentry {
font-weight: 600;
}
/*** Tables ***/
table {
font-size: 1em;
background-color: #fafcff;
border: 1px solid #909090;
color: #2a2a2a;
padding: 5px 5px 2px;
border-collapse: collapse;
}
td, th {
border: thin dotted gray;
}
/*** Inputs ***/
input[type=text] {
font-size: 115%;
width: 30em;
}
input[type=submit] {
font-size: 125%;
}
select {
font-size: 125%;
}
3条答案
按热度按时间00jrzges1#
看看这段描述:https://github.com/ua-parser/uap-python下面的代码可以成功获取浏览器信息,我已经测试成功了,大家可以试试:
bqucvtff2#
不传输浏览器数据。
溶液:
将行
req.user_agent.browser
更改为req.headers.get('User-Agent')
c9qzyr3d3#
关于您的问题,浏览器返回 None,即使在放入
phrase
后,我知道这会阻止您获得结果(因为我在看同一本书),可能是源于vsearch.py
文件。您是否确保在def search4vowels
和def search4letters
函数中使用return
语句?此外,请确保
vsearch.py
已正确保存为sdist文件