Найти - Пользователи
Полная версия: TypeError: The view function for '*******' did not return a valid response
Начало » Web » TypeError: The view function for '*******' did not return a valid response
1
sepomd
Всем привет. Недавно начал изучать Flask и вот решил сделать первый проект - страничку ресторана, с возможностью резервирования столика, подписки на рассылку и прочее.

Проблемы появилась когда делал функционал странички резервирования столика. После ввода всех данных, появляется ошибка - “TypeError: The view function for ‘booking’ did not return a valid response. The function either returned None or ended without a return statement.”

Как бы понятно что функция должна хоть что-то возвращать и в самой фунции я прописал return в случае GET запроса и тот который должен сделать редирект на главную страницу в случае удачного POST запроса.

Решил в функции booking перед return'ами поставить по print'у. Получается в консоли сначала появляется принт из exception и потом принт который после return render_template('booking.html')

Подскажите пожалуйста в чём может быть проблема и как её устранить.

Ниже привожу свой код:

Создаём таблицу:
 from flask import Flask, request, redirect, render_template, url_for
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///restaurant_booking1.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Booking(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(50), nullable=False)
    lastname = db.Column(db.String(50), nullable=False)
    email = db.Column(db.String(20), nullable=False)
    phone = db.Column(db.String(50), nullable=False)
    birthdate = db.Column(db.String(50), nullable=False)
    booking_date = db.Column(db.String(50), nullable=False)
    booking_time = db.Column(db.String(50), nullable=False)
    guests_nr = db.Column(db.String(5), nullable=False)
    notes = db.Column(db.Text(1000))
    def __repr__(self):
        return '<Booking %r>' % self.id

Функция booking:
 @app.route('/booking', methods=['POST', 'GET'])
def booking():
    if request.method == 'POST':
        firstname = request.form['firstname']
        lastname = request.form['lastname']
        phone = request.form['phone']
        email = request.form['email']
        birthdate = request.form['birthdate']
        booking_date = request.form['booking_date']
        booking_time = request.form['booking_time']
        guests_nr = request.form['guests_nr']
        notes = request.form['notes']
        reservation = Booking(firstname=firstname, lastname=lastname, email=email, phone=phone, birthdate=birthdate,
                              booking_date=booking_date, booking_time=booking_time, guests_nr=guests_nr, notes=notes)
        try:
            db.session.add(reservation)
            db.session.commit()
            return redirect('/booking', code=303)
        except:
            return "An error has been occurred. Please, try again later"
    else:
        return render_template('booking.html')

html код (вдруг там вся проблема):
 {% block body %}
    <div class="booking-container">
        <form method="post">
            <input type="text" name="firstname" id="firstname" class="form-control" placeholder="First Name" required>
            <input type="text" name="lastname" id="lastname" class="form-control" placeholder="Last Name" required>
            <input type="text" name="email" id="email" class="form-control" placeholder="Email" required>
            <input type="text" name="phone" id="phone" class="form-control" placeholder="Phone Number" required>
            <input type="text" name="birthdate" id="birthdate" class="form-control" placeholder="Date of Birth" required>
            <input type="text" name="booking_date" id="booking_date" class="form-control" placeholder="Reservation Date" required>
            <input type="text" name="booking_time" id="booking_time" class="form-control" placeholder="Reservation Time" required>
            <input type="text" name="guests_nr" id="guests_nr" class="form-control" placeholder="Number of Guests" required>
            <textarea name="notes" id="notes" class="form-control" placeholder="Notes"></textarea>
            <input type="submit" class="btn-submit" value="Sent">
        </form>
    </div>
{% endblock %}
sepomd
ошибка оказалось очень простая
 if request.method == 'POST':

'POST' надо писать в квадратных скобках


Правда теперь появилась новая ошибка. после удачного заполнения формы, вся инфа записывается в БД. Теперь я хочу вывести эти данные в странице в админке, к которой должен иметь доступ админ.

Пишу следующий код:
 @app.route('/admin_panel/admin_panel_bookings/')
def admin_panel_bookings():
    bookings = Booking.query.order_by(Booking.email).all()
    return render_template('admin_panel_bookings.html', bookings=bookings)

и html:
 {% block body %}
    <div class="adm_bookings_container">
    <h1>List of Bookings</h1>
     {{ subscribers[0].email }}
    </div>
{% endblock %}

Для теста хочу вывести только записи из колонки с емейлами, но в ответ получаю вот такую ошибку:
“sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: booking.firstname
[SQL: SELECT booking.id AS booking_id, booking.firstname AS booking_firstname, booking.lastname AS booking_lastname, booking.email AS booking_email, booking.phone AS booking_phone, booking.birthdate AS booking_birthdate, booking.booking_date AS booking_booking_date, booking.booking_time AS booking_booking_time, booking.guests_nr AS booking_guests_nr, booking.notes AS booking_notes
FROM booking ORDER BY booking.email]”

Я так понимаю, данной таблицы с букингами просто нет в БД. Саму БД создаю в терминале командами:
>> from app import db
>> db.create_all()

После чего создаётся сама БД. Но видимо я что-то делаю не так ибо ничего не работает. Подскажите в чём моя ошибка и как сделать чтоб всё это заработало.
py.user.next
sepomd
ошибка оказалось очень простая
  
if request.method == 'POST':
'POST' надо писать в квадратных скобках
Не, что-то не то ты нашёл, значит.

Лучше попробуй try … except … убрать там и без него посмотри.
sepomd
py.user.next
Да, вы были правы. Решил проверить если редирект работает правильно, указал другую страницу и после нажатия на кнопку сабмит, ничего не произошло. Просто исчезают данные введенные в формы и всё. Я так понимая срабатывает
 else:
        return render_template('booking.html')

и этот ретурн должен срабатывать в случае когда у нас GET запрос. Но вот мне не понятно почему первое условие не срабатывает, ведь если проверяю через Inspect то запрос указан как POST
sepomd
Решил сделать ещё одну функцию. Эта функция отвечает за подписку на всякие новости и пр.

def newsletter_signup():
if request.method == 'POST':
first_name = request.form['firstname']
last_name = request.form['lastname']
email = request.form['email']

newsletter = Newsletter(FirstName=first_name, LastName=last_name, Email=email)

db.session.add(newsletter)
db.session.commit()

return redirect(url_for('/'))


else:
return render_template('newsletter-signup.html')

В этой функции указал метод POST без квадратных скобок
  if request.method == 'POST':

И теперь при нажатии на кнопку submit выскакивает вот такая ошибка:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: newsletter


Становится понятно что вся проблема именно в работе с БД. Может кто знает как быть в данном случае? Так же хотелось бы узнать, как проверить если таблицы создались в БД или нет.

 from flask import Flask, request, redirect, render_template, url_for
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///restaurant_booking1.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Booking(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(50), nullable=False)
    lastname = db.Column(db.String(50), nullable=False)
    email = db.Column(db.String(20), nullable=False)
    phone = db.Column(db.String(50), nullable=False)
    birthdate = db.Column(db.String(50), nullable=False)
    booking_date = db.Column(db.String(50), nullable=False)
    booking_time = db.Column(db.String(50), nullable=False)
    guests_nr = db.Column(db.String(5), nullable=False)
    notes = db.Column(db.Text, nullable=True)
    def __repr__(self):
        return '<Booking %r>' % self.id
class Newsletter(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    FirstName = db.Column(db.String(50), nullable=False)
    LastName = db.Column(db.String(50), nullable=False)
    Email = db.Column(db.String(20), nullable=False)
    def __repr__(self):
        return '<Newsletter %r>' % self.id
sepomd
Ура товарищи!

На вторые сутки я всё-таки добился чтобы эта хрень заработала, правда пришлось кое-что переписать.
Теперь вопрос такой - кто знает хороший учебник/курс по Фласку/jinja?

код моего решения:
 class Booking(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(50))
    lastname = db.Column(db.String(50))
    email = db.Column(db.String(20))
    phone = db.Column(db.String(50))
    birthdate = db.Column(db.String(50))
    booking_date = db.Column(db.String(50))
    booking_time = db.Column(db.String(50))
    guests_nr = db.Column(db.String(5))
    notes = db.Column(db.Text)
    # def __repr__(self):
    #     return '<Booking %r>' % self.id
    def __init__(self, firstname, lastname, email, phone, birthdate, booking_date, booking_time, guests_nr, notes):
        self.firstname = firstname
        self.lastname = lastname
        self.email = email
        self.phone = phone
        self.birthdate = birthdate
        self.booking_date = booking_date
        self.booking_time = booking_time
        self.guests_nr = guests_nr
        self.notes = notes
class Newsletter(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(50))
    lastname = db.Column(db.String(50))
    email = db.Column(db.String(20))
    # def __repr__(self):
    #     return '<Newsletter %r>' % self.id
    def __init__(self, firstname, lastname, email):
        self.firstname = firstname
        self.lastname = lastname
        self.email = email

 @app.route('/booking/', methods=['GET', 'POST'])
def booking():
    if request.method == ['POST']:
        if not request.form['firstname'] or not request.form['lastname'] or not request.form['email'] or not \
        request.form['phone'] or not request.form['birthdate'] or not request.form['booking_date'] or not request.form[
            'booking_time'] or not request.form['guests_nr'] or not request.form['notes']:
            
        else:
            bookings = Booking(request.form['firstname'], request.form['lastname'], request.form['email'],
                               request.form['phone'], request.form['birthdate'], request.form['booking_date'],
                               request.form['booking_time'], request.form['guests_nr'], request.form['notes'])
            db.session.add(bookings)
            db.session.commit()
            
            return redirect(url_for('index'))
    return render_template('booking.html')

 @app.route('/newsletter-signup/', methods=['GET', 'POST'])
def newsletter_signup():
    if request.method == 'POST':
        if not request.form['firstname'] or not request.form['lastname'] or not request.form['email']:
            
        else:
            newsletters = Newsletter(request.form['firstname'], request.form['lastname'], request.form['email'])
            db.session.add(newsletters)
            db.session.commit()
            
            return redirect(url_for('index'))
    return render_template('newsletter-signup.html')

 <table>
    <thead>
        <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Email</th>
        </tr>
    </thead>
    <tbody>
    {% for newsletters in Newsletter %}
        <tr>
            <td>{{ newsletters.firstname }}</td>
            <td>{{ newsletters.lastname }}</td>
            <td>{{ newsletters.email }}</td>
        </tr>
    {%  endfor %}
    </tbody>
</table>
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB