【问题标题】:Why does my Flask-SQLAlchemy update query not change my table content为什么我的 Flask-SQLAlchemy 更新查询不会更改我的表格内容
【发布时间】:2020-09-30 10:31:11
【问题描述】:

我正在制作一个烧瓶网站,其中有一个 SQLite 数据库,其中有一个名为 mainscreen 的表。在我的主屏幕上,我有一些从主屏幕 - 内容列中获取的文本。我正在尝试从我的表单中的 textarea 中检索数据,该表单应该更新我的主屏幕表。虽然我正确地被重定向到我的 home.html,但我看不到正在做的更改,即我的表没有得到更新。


MainScreen 表结构


|- mainscreen
    |- id = integer - primary key
    |- content = varchar(1000)

所需代码


flaskapp.py

from flask import Flask, render_template, [...]
from flask_login import [...]
from myproject.__init__ import User, MainScreen
from werkzeug.security import generate_password_hash,check_password_hash
from flask_sqlalchemy import SQLAlchemy
import os

app = Flask(__name__)


app.config['SECRET_KEY'] = [...]
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.abspath(os.path.join(os.path.dirname( __file__ ), 'data.sqlite'))

db = SQLAlchemy(app)

@app.route('/updated', methods=['POST', 'GET'])
def change_home():
    if request.method == 'GET':
        new_content = request.form.get('home', False)
        mainContent = MainScreen.query.get(1)
        mainContent.content = new_content
        db.session.commit()
        return redirect(url_for('home'))

    else:
        return redirect(url_for('login'))


@app.route('/loggedin', methods=['POST', 'GET'])
def login():
    [... ...]
    datas = {}
    datas['content'] = onlycontent
    return render_template('loggedin.html', data=datas)

myproject / __init __.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import [...]
from flask_login import UserMixin
import os

app = Flask(__name__)
db = SQLAlchemy(app)


app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.abspath(os.path.join(os.path.dirname( __file__ ), os.pardir, 'data.sqlite'))


class MainScreen(db.Model, UserMixin):

    __tablename__ = 'mainscreen'

    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(1000), unique=False, nullable=False)

    def __init__(self, id, content):
        self.id = id
        self.content = content

    def __repr__(self):
        return f'<MainScreen {self.id} {self.content}>'

loggedin.html

    <form action="{{url_for('change_home')}}" method="get">
        <table>
            <tr>
                <td width="10%">
                    <h4>Home Page</h4>
                </td>

                <td class="padding-right:5%">
                    <textarea name="home" rows="7">{{data['content']}}</textarea>
                </td>
                <td>
                    <input type="submit" class="btn btn-primary"></input>
                </td>
            </tr>
        </table>    
    </form>

home.html

@app.route('/home')
@app.route('/')
def home():
    datas = {}
    MainContent = MainScreen.query.get(1)
    content = MainContent.content
    datas['aboutme'] = content
    return render_template('home.html', data=datas)

点冻结

Flask==1.1.2
Flask-Login==0.5.0
Flask-Migrate==2.5.3
Flask-SQLAlchemy==2.4.4
SQLAlchemy==1.3.19
SQLAlchemy-Utils==0.33.2

更新 1


设置一些断点后,我的new_content 变量似乎没有获取数据。它返回None。由于我的内容列设置为 NOT NULL,这可能是它没有得到更新的原因。我需要弄清楚为什么我的 new_content 变量没有检索数据


更新 2


看来我的变量 mainContent.content 现在正在更新 - 我必须通过将 home 放在双引号中来检索数据。现在我的db.session.commit() 似乎不起作用。从一些在线研究中,我发现我在初始化 flask-sqlalchemy 的方式上可能犯了一些错误,所以我添加了更多与我的初始化相关的代码。谢谢,感谢您的帮助

【问题讨论】:

  • 如果你只是说它不起作用,就不可能猜到哪里出了问题。你必须自己调试它。看看你在 python 中有什么值,你传递给模板的确切内容以及你在模板中看到的内容。然后,您应该向我们提供相关信息,而不是您的完整申请。
  • @zvone 我已经提供了相关代码。出了什么问题是我的数据库没有得到更新。我尝试了几个建议,实际上我的最后一行正确执行,这意味着我的数据库更新语句没有任何错误。但是我的数据库由于某种原因没有改变
  • 嗯,首先,您提供的代码中没有数据库更新。至少我看不到。其次,尚不清楚问题是仅在模板中,还是在python代码中。这可以通过调试发现。
  • @zvone new_content = request.form.get('home', False) mainContent = MainScreen.query.get(1) mainContent.content = new_content db.session.commit() 是更新查询。我试过调试它,但找不到问题,因此我把它带到了 SO

标签: python python-3.x flask sqlalchemy flask-sqlalchemy


【解决方案1】:

这可能是因为您正在通过GET 发送数据——请尝试使用request.args.get("home"),看看是否可行。

【讨论】:

  • @rishi 你能显示你添加断点的代码吗?请尝试在该方法中注释除new_content = request.form.get('home', False)import pdb; pdb.set_trace() 之外的所有代码,以检查数据是否正确接收。
  • 您应该在终端中看到 (Pdb) 交互式调试器,您可以在其中检查您的代码。看看这个关于如何使用pdbrealpython.com/lessons/getting-started-pdb的短视频
  • @rishi 好的,所以看起来数据可能没有正确发送。尝试在调试器中检查request.form 的值并查看表单提交发送的内容。我建议您也不要使用GET 提交表单。
  • @rishi 您能否尝试在&lt;input type="text" name="test" /&gt; 表单中添加一个额外的字段,并在您处理表单的方法中添加一个断点并告诉我request.form 的值是什么(不是new_content)?
  • @rishi 好的,所以问题似乎你需要使用带有双引号的request.form.get("home") or request.form["home"],对吧?现在尝试禁用调试器,再次提交表单并查看数据是否保存在数据库中。
【解决方案2】:

您正在使用data['content'] 填充您的文本区域:

<textarea name="home" rows="7">{{data['content']}}</textarea>

这应该是空的,因为您没有将data['content'] 中的任何值传递给render_template

@app.route('/home')
@app.route('/')
def home():
    datas = {}  # empty dict
    MainContent = MainScreen.query.get(1)
    content = MainContent.content
    datas['aboutme'] = content  # set datas['aboutme'] but not datas['content']
    return render_template('home.html', data=datas)  # pass {'aboutme': content} to Jinja

您应该在home() 中设置datas['content'] = content 或在loggedin.html 中访问data['aboutme']

【讨论】:

  • 抱歉,我有一个 def login 函数,我在其中设置了另一个字典数据,我在其中设置了 datas['content'] = my content.. 所以我不相信我正在访问我的数据不正确。我已经完全按照我在 home 函数中的方式访问了数据。我已经更新了我的功能
  • 为了“[...] 将特定于用户的信息从一个请求存储到下一个请求”,您必须使用session 对象(请参阅here)。在任何情况下,通过设置datas = {} 可以清除它并删除之前存在的所有内容。
  • 因为我的信息是直接从数据库中显示出来的,所以我的datas 被重置并不重要。我无法对我的数据库进行任何更改,这就是问题
【解决方案3】:

可能的问题是由于您没有传递mainContent 来存储它。


@app.route('/updated', methods=['POST', 'GET'])
def change_home():
    if request.method == 'GET':
        new_content = request.form.get('home', False)
        mainContent = MainScreen.query.get(1)
        mainContent.content = new_content
        db.session.add(mainContent)  # add this line and this should work
        db.session.commit()
        return redirect(url_for('home'))

    else:
        return redirect(url_for('login'))

您还试图在GET 方法中访问表单数据,我认为该方法不包含前端的form 数据。

if request.method == 'GET':
    new_content = request.form.get('home', False)

如果您需要设置一些信息,您要么需要使用POST发送表单数据,要么需要将您的期望值存储在session['&lt;key&gt;']中。

我希望这将有助于找到问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 2014-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多