为什么《Head First Python 2nd Edition》一书中的webapp的数据库不能正常工作?

x6h2sr28  于 2022-12-27  发布在  Python
关注(0)|答案(3)|浏览(196)

我目前正在通过阅读《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%;
  }
00jrzges

00jrzges1#

看看这段描述:https://github.com/ua-parser/uap-python下面的代码可以成功获取浏览器信息,我已经测试成功了,大家可以试试:

from ua_parser import user_agent_parser    #Note the code here

web_detial = str(request.user_agent)    #Note the code here
user_browser = user_agent_parser.ParseUserAgent(web_detial)    #Note the code here
browser = user_browser['family']    #Note the code here

---
cursor.execute(_SQL, (req.form['phrase'],
                      req.form['letters'],
                      req.remote_addr,
                      browser,    #Note the code here
                      res, ))
bqucvtff

bqucvtff2#

不传输浏览器数据。
溶液:
将行req.user_agent.browser更改为req.headers.get('User-Agent')

c9qzyr3d

c9qzyr3d3#

关于您的问题,浏览器返回 None,即使在放入phrase后,我知道这会阻止您获得结果(因为我在看同一本书),可能是源于vsearch.py文件。您是否确保在def search4vowelsdef search4letters函数中使用return语句?
此外,请确保vsearch.py已正确保存为sdist文件

相关问题