Мое приложение для колб основано на мега-учебном пособии Мигеля Гринберга XIV с некоторыми дополнительными функциями, и все оно работало нормально, и к нему можно было получить доступ из браузера на localhost: 5000. Я решил переключиться на подход к фабрике приложений согласно XV учебнику Гринберга, НО без чертежей. Теперь, когда я ввожу localhost: 5000, я получаю URL-адрес не найден. Я полагаю, что мои маршруты не были найдены по какой-то причине.
Я тщательно проработал XV учебник Гринберга и связанный с ним код и выровнял все, кроме чертежей. Вот ссылки, которые я изучил и на которых основано мое текущее приложение: -
https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xv-a-better-application-structure
http://flask.pocoo.org/docs/1.0/tutorial/factory/
Ответ Дэйва В. Смита в Настройка Python Flask App для использования фабрики "create_app" и использования базы данных в классе модели
и др.
Из того, что я прочитал, реализация фабрики приложений должна быть очень простой. Примеры работают.
Сервер фляг запускается из командной строки в venv, как всегда.
Вот моя структура каталогов.
myapp
app.py
config.py
...
/app
__init__.py
routes.py
models.py
forms.py
...
Вот код, слегка упрощенный для ясности.
# app.py
#=============================================
from app import create_app, db
from app.models import User, Post
app = create_app()
@app.shell_context_processor
def make_shell_context():
return {'db': db, 'User': User, 'Post' :Post}
# __init__.py
#=============================================
...
import os
from flask import Flask, request, current_app
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
...
from config import Config
db = SQLAlchemy()
migrate = Migrate()
...
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
db.init_app(app)
migrate.init_app(app, db)
...
# logging, email servers, etc configured
return app
from app import models
# routes.py
#=============================================
from datetime import datetime
from flask import render_template, flash, redirect, url_for, request, g, \
jsonify, current_app
...
from app import app, db
from app.forms import LoginForm, RegistrationForm, EditProfileForm,
PostForm,ResetPassword,RequestForm, ResetPasswordForm
from app.models import User, Post
...
@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
@login_required
def index():
form = PostForm()
if form.validate_on_submit():
...
page = request.args.get('page', 1, type=int)
...
return render_template('index.html', title=_('Home'), form=form,
posts=posts.items, next_url=next_url,
prev_url=prev_url)
@app.route ....
# models.py
#=============================================
from datetime import datetime
from hashlib import md5
from time import time
from flask import current_app
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
import jwt
from app import db, login
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
...
Это может быть неуместно, но это одна вещь, которую я попробовал. Обратите внимание, что в файле rout.py у меня есть from app import app, db
, если я удаляю app
и добавляю from flask import current_app
, тогда декораторы @app
отображаются как неопределенные.
Еще один момент, потому что проблема с маршрутами. Если я изменю последнюю строку с __init__.py
на from app import routes, models
, я получу другую ошибку.
flask.cli.NoAppException
flask.cli.NoAppException: While importing "metapplica", an ImportError was raised:
Traceback (most recent call last):
File "c:\users\markko~1\dropbox\python\projects\metapp~1\venv\lib\site-packages\flask\cli.py", line 236, in locate_app
__import__(module_name)
File "C:\Users\Mark Kortink\Dropbox\Python\projects\metapplica\metapplica.py", line 1, in <module>
from app import create_app, db, cli
File "C:\Users\Mark Kortink\Dropbox\Python\projects\metapplica\app\__init__.py", line 75, in <module>
from app import routes, models
File "C:\Users\Mark Kortink\Dropbox\Python\projects\metapplica\app\routes.py", line 8, in <module>
from app import app, db
ImportError: cannot import name 'app' from 'app' (C:\Users\Mark Kortink\Dropbox\Python\projects\metapplica\app\__init__.py)
Именно эта ошибка заставила меня попробовать current_app
изменение, упомянутое выше.
Я запускаю приложение вот так.
cd C:\Users\...\myapp
venv\Scripts\activate
set FLASK_APP=app.py
set FLASK_DEBUG=1
flask run
Я знаю, что проблема, вероятно, действительно простая, но кто-нибудь может понять, почему приведенный выше код даст URL-адрес, который не найден, или не сможет найти маршруты?
=== СЛЕДУЮЩАЯ ФАЗА ================
Следуя рекомендациям @silver ниже, мои новые имена: -
myapp
runapp.py
...
/mapp
__init__.py
...
Я просмотрел весь свой код и изменил from app[.xxx] import yyy
на from myapp[.xxx] import yyy
. Это вывело несколько новых ошибок, где я ссылался на app
, которые я исправил, подставив current_app
.
Моя новая ошибка
RuntimeError
RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context(). See the
documentation for more information.
Traceback (most recent call last)
File "C:\Users\Mark Kortink\Dropbox\Python\projects\myapp\runapp.py", line 1, in <module>
from mapp import create_app, db, cli
File "C:\Users\Mark Kortink\Dropbox\Python\projects\myapp\mapp\__init__.py", line 75, in <module>
from mapp import routes, models
File "C:\Users\Mark Kortink\Dropbox\Python\projects\myapp\mapp\routes.py", line 16, in <module>
@current_app.before_request