Почему мой запрос на обновление Flask-SQLAlchemy не изменяет содержимое моей таблицы

#python #python-3.x #flask #sqlalchemy #flask-sqlalchemy

#python #python-3.x #flask #sqlalchemy #flask-sqlalchemy

Вопрос:

Я создаю веб-сайт flask, на котором у меня есть база данных SQLite с таблицей под названием mainscreen. На моем главном экране у меня есть текст, полученный из столбца содержимого главного экрана. Я пытаюсь извлечь данные из моей текстовой области в моей форме, которая должна обновить мою таблицу главного экрана. Хотя я правильно перенаправляюсь на мой home.html , я не вижу, как вносятся мои изменения, т.е. моя таблица не обновляется.


Структура таблицы главного экрана


 |- 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)
  

pip зависает

 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, поэтому я добавил еще немного кода, связанного с моей инициализацией. Спасибо, ваша помощь приветствуется

Комментарии:

1. Невозможно угадать, что пошло не так, если вы просто скажете, что это не работает. Вы должны отладить его самостоятельно. Посмотрите, какие значения у вас есть в python, что именно вы передаете в шаблон и что вы видите в шаблоне. Затем вы должны предоставить нам ту информацию, которая имеет отношение к делу, вместо вашего полного приложения.

2. @zvone Я предоставил соответствующий код. Что происходит не так, так это то, что моя база данных не обновляется. Я попробовал несколько предложений, на самом деле моя последняя строка выполняется правильно, что означает, что в моем заявлении об обновлении базы данных нет ошибок. Но моя база данных по какой-то причине не меняется

3. Ну, во-первых, в предоставленном вами коде нет обновления базы данных. По крайней мере, я этого не вижу. Во-вторых, неясно, проблема только в шаблоне или в коде python. Это можно обнаружить путем отладки.

4. @zvone new_content = request.form.get('home', False) mainContent = MainScreen.query.get(1) mainContent.content = new_content db.session.commit() — это запрос на обновление. Я попытался отладить его и не смог найти проблему, поэтому я привел его к SO

Ответ №1:

Возможно, это связано с тем, что вы отправляете данные повторно GET — попробуйте request.args.get("home") вместо этого и посмотрите, работает ли это.

Комментарии:

1. @rishi можете ли вы показать код, в котором вы добавляете точку останова? пожалуйста, попробуйте прокомментировать весь код в этом методе, кроме new_content = request.form.get('home', False) и import pdb; pdb.set_trace() просто для проверки правильности получения данных.

2.Вы должны увидеть (Pdb) интерактивный отладчик в терминале, где вы сможете проверить свой код. Взгляните на это короткое видео о том, как использовать pdb realpython.com/lessons/getting-started-pdb

3. @rishi хорошо, похоже, что данные могут быть отправлены неправильно. Попробуйте проверить значение request.form в отладчике и посмотреть, что отправляется с отправкой формы. Я рекомендую вам также не использовать GET для отправки формы.

4. @rishi не могли бы вы попробовать добавить дополнительное поле в форму <input type="text" name="test" /> и добавить точку останова в метод, в котором вы обрабатываете форму, и сказать мне, какое значение request.form (not new_content ) ?

5. @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
  

Вы должны либо установить datas['content'] = content , home() либо получить доступ data['aboutme'] loggedin.html .

Комментарии:

1. Прошу прощения, у меня есть def login функция, в которой я устанавливаю другие данные словаря, в которых я установил datas['content'] = my content .. Поэтому я не верю, что я неправильно обращаюсь к своим данным. Я получил доступ к данным точно так же, как и в моей домашней функции. Я обновил свою функцию

2. Для того, чтобы «[…] сохранять информацию, специфичную для пользователя, от одного запроса к следующему», вам нужно будет использовать session объект (см. Здесь ). В любом случае, установив datas = {} его, вы очистите его и удалите все, что было там раньше.

3. Поскольку моя информация отображается непосредственно из базы данных, не должно иметь значения, что мой 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['<key>'] ожидаемое значение.

Я надеюсь, что это поможет найти проблему.