I got this error: ImportError: cannot import name 'admin' from ' admin.blueprint' after I'm in the module blueprint.py imported Post from models.py please help me to understand the structure of the application in order to avoid such errors in the future.
<module main.py>
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from admin.blueprint import admin
from config import Config
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
app.register_blueprint(admin, url_prefix='/admin')
import views
if __name__ == '__main__'
db.create_all()
app.run(debug=True)`
<module blueprint.py>
from flask import Blueprint, redirect, render_template, request, url_for
from config import ConfigAdmin
from models import Post
admin = Blueprint('admin', __name__, template_folder='templates', static_folder='static')
#admin.route('/')
def admin_login():
return render_template('admin/admin-login.html')
#admin.route('/admin-panel', methods=['POST'])
def admin_panel():
if request.form['username'] == ConfigAdmin.ADMIN_NAME and request.form['password'] == ConfigAdmin.ADMIN_PASS:
return render_template('admin/admin-panel.html')
else:
return redirect(url_for('admin.admin_login'))
#admin.route('/create-post')
def create_post():
return render_template('admin/create-post.html')
#admin.route('/add-post', methods=['POST'])
def add_post():
if request.method == 'POST':
body = Post(post_title=request.form['title'], post_text=request.form['article'], post_img=redirect.form['file'])
db.session.add(body)
db.session.commit()
return redirect(url_for('index'))
else:
return "Err"
<module models.py>
from main import db
class Admin(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20), unique=True)
passw = db.Column(db.String(20), unique=True)
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(50), unique=True)
text = db.Column(db.String(500), unique=True)
img = db.Column(db.String(50))
[error][1]
[structure][2]
[1]: https://i.stack.imgur.com/cgrbH.png
[2]: https://i.stack.imgur.com/fDr7O.png
Have you tried creating the following app? Flask Tutorial App - Flaskr blog
I highly recommend following this structure if you're starting out.
looks as follows:
/home/user/Projects/flask-tutorial
├── flaskr/
│ ├── __init__.py
│ ├── db.py
│ ├── schema.sql
│ ├── auth.py
│ ├── blog.py
│ ├── templates/
│ │ ├── base.html
│ │ ├── auth/
│ │ │ ├── login.html
│ │ │ └── register.html
│ │ └── blog/
│ │ ├── create.html
│ │ ├── index.html
│ │ └── update.html
│ └── static/
│ └── style.css
├── tests/
│ ├── conftest.py
│ ├── data.sql
│ ├── test_factory.py
│ ├── test_db.py
│ ├── test_auth.py
│ └── test_blog.py
├── venv/
├── setup.py
└── MANIFEST.in
If you would like it to function in your current app I suggest you create a admin.py inside the same folder as your main.py
from flask import Blueprint, redirect, render_template, request, url_for
from config import ConfigAdmin
from models import Post
bp = Blueprint('admin', __name__, template_folder='templates', static_folder='static')
then import it in main.py as follows
from admin import bp as adminbp
app.register_blueprint(adminbp, url_prefix='/admin')
Related
I am a beginner with Flask and I have created a project with an MVC structure
CODE :
.
├── app
│. │── main.py
│ ├── controllers
│ │ ├── dbscan.py
│ │ ├── home.py
│ │ └── kmeans.py
│ ├── models
│ │ ├── dbscan.py
│ │ └── kmeans.py
│ ├── static
│ │ └── XXXX
│ └── views
│ └── XXXX
└── main.py
File main.py
from flask import Flask
app = Flask(
__name__,
template_folder='app/views',
static_folder='app/static'
)
if __name__ == "__main__":
app.run(debug=True)
File home.py
from flask import render_template
#app.route("/")
def home():
return render_template('home.html')
ISSUE :
I already understood the problem but I don't know how to fix it...
There is no link between the controllers files and the main.py
So, how I can link all routes present in controllers folder and main.py ?
UPDATE :
home.py
from flask import Blueprint, render_template
home_hdl = Blueprint('home_hdl', __name__, template_folder='views')
#home_hdl.route("/")
def home():
return render_template('home.html')
main.py
from flask import Flask
from app.controllers.home import home_hdl
app = Flask(
__name__,
template_folder='app/views',
static_folder='app/static'
)
app.register_blueprint(home_hdl)
if __name__ == "__main__":
app.run(debug=True)
Folders
.
├── app
│ ├── controllers
│ │ ├── __init__.py
│ │ ├── dbscan.py
│ │ ├── home.py
│ │ └── kmeans.py
│ ├── main.py
│ ├── models
│ │ └── XXXX
│ ├── static
│ │ └── XXXX
│ └── views
│ └── XXXX
└── XXXX
Try this
Define a handler in each of the files you have under the controllers folder (the ones that will handle routing).
E.g. for the dbscan.py, you could have
from flask import Blueprint
dbscan_handlers = Blueprint('dbscan_handlers', __name__, template_folder='views')
# Your routes (in the dbscan.py file) will then be something like this
#dbscan_handlers.route('/xyz/'):
.....
#dbscan_handlers.route('/def/'):
....
Then you register the handler in main.py
from controllers.dbscan import dbscan_handlers
app.register_blueprint(dbscan_handlers)
Note that to do from controllers.abc import xyz, you need to have an __init.py__ file in controllers. The file can be empty.
When someone accesses your app, it will go to main.py and if the route is of the pattern /xyz/, it will be handled by dbscan.py file
Currently i'm having a file structure like below.
├── src
│ ├── common
│ │ ├──constants.py
│ │ └──configs.py
│ ├── utils
│ │ ├──module1.py
│ │ └──module2.py
│ └── service
│ │ ├──module3.py
│ │ └──module24.py
│ └── main.py
├── test
│ ├── utils
│ │ ├──test_module1.py
│ │ └──test_module2.py
My test_module1.py includes
# test_module1.py
import sys
sys.path.append("./.")
from src.utils.module1 import filter_file
from unittest import TestCase, main, mock
utils/module1.py includes
# module1.py
from common.constants import LOG_FORMAT, TIME_FORMAT
...
Here, when i try to run test_module1.py file from root i get an error saying that,
$- python3 test/utils/test_module1.py
$- ModuleNotFoundError: No module named 'common.constants'
what is the issue here
Tested it, works like this on Windows:
├── src
│ └── utils
│ └──lib.py
├── test
│ └── utils
│ └──bla.py
lib.py:
def test():
print("woo")
bla.py:
import os
import sys
sys.path.append(".." + os.sep + "..")
from src.utils.lib import test
test()
I'm an aspnet core developer and trying to do a test project in python using the flask framework. But because of my lack of understanding of the structure of python projects I'm having hard time compiling it. I don't understand why does it care if I keep my python file in another directory. In C# you can access all classes inside the same namespace without importing anything.
Here's my python flask project structure looks like. I can't seem to work it with this way. I'm trying to import my home_service.py inside home.py file where home routes are present (in aspnet's term controller) and the logger doesn't seem to be accessible either.
And home_service.py can't import db_util.py either.
Would any python flask expert please guide me in the right direction?
/../../Projects/flask-test-project
├── test-project/
│ ├── __init__.py
│ └── static/
│ └── site.css
│ ├── templates/
│ │ ├── layout.html
│ │ ├── home.html
│ │ ├── offerings.html
│ │ ├── login.html
│ │ ├── register.html
│ │ ├── 404.html
│ │ ├── 500.html
│ ├── views/
│ │ ├── __init__.py
│ │ ├── home.py
│ │ ├── offerings.py
│ │ ├── login.py
│ │ ├── register.py
│ ├── service/
│ │ ├── home_service.py
│ │ ├── db_util.py
├── flask-venv-for-ubuntu/
├── requirements.txt
└── run.py
**run.py**
from test-project import app
from datetime import datetime
import logging
todays_date = datetime.today().strftime('%Y%m%d')
logging.basicConfig(filename='error'+ todays_date+'.log',level=logging.Trace)
app.run(debug=True)
app.logger.trace(“Inside run.py”)
**__init__.py**
from flask import g, Blueprint, request
from psycopg2
# $ pip install sentry-sdk[flask]
from werkzeug.exceptions import HTTPException
app = Flask(__name__)
#app.errorhandler(404)
def not_found(error):
return render_template('404.html')
#app.errorhandler(HTTPException)
def handle_exception(e):
app.logger.error(e)
return render_template(“500.html”)
#app.teardown_appcontext
def close_connection():
db = getattr(g, '_database', None)
if db is not None:
db.close()
from test-project.views import home
from test-project.views import login
from test-project.views import register
from test-project.views import offerings
app.register_blueprint(home.mod)
app.register_blueprint(login.mod)
app.register_blueprint(register.mod)
app.register_blueprint(offerings.mod)
**db_util.py**
from flask import g
import psycopg2
POSTGRES_CONNECTIONSTRING = “……...”
def get_db():
db = getattr(g, '_database', None)
if db is None:
db = g._database = psycopg2.connect(POSTGRES_CONNECTIONSTRING)
return db
def query_db(query, args=(), one=False):
try:
cur = get_db().execute(query, args)
rv = cur.fetchall()
cur.close()
return (rv[0] if rv else None) if one else rv
finally:
if(cur)
cur.close()
**home_service.py**
import db_util
def get_something
app.logger.Debug(“get_something started”)
return query_db(“select count(*) as myCount from table1;”)
**home.py**
import home_service
mod = Flask(“home”,__name__)
#mod.route(“/something”)
def something():
app.logger.Debug(“get_something started”)
return render_template(“home.html”, count_of_table1=get_something().myCount)
Please don't recommend me to use SQLAlchemy or any other orm. I want to do it my way. Thanks!
I am trying to setup up some test cases using pytest for a project i'm working on and have setup my directory like so.
C:.
│ OpenGLTestCase.py
│ Sprite.py
│ SpriteManager.py
│ SpriteRenderer.py
│ Texture.py
│ __init__.py
│
├───.pytest_cache
│ │ .gitignore
│ │ CACHEDIR.TAG
│ │ README.md
│ │
│ └───v
│ └───cache
│ lastfailed
│ nodeids
│ stepwise
│
├───tests
│ │ colorGrid.png
│ │ OpenGLTestCaseExample.py
│ │ OpenGLTestCaseExample2.py
│ │ test.png
│ │ test.svg
│ │ test2.png
│ │ test3.png
│ │ test_over_colorGrid_at_128left_256_top.png
│ │ test_over_uvGrid_at_128left_256_top.png
│ │ test_render_image_expected.png
│ │ test_render_triangle_expected.png
│ │ test_sprite_manager.py
│ │ test_Texture.py
│ │ uvGrid.png
│ │
│ └───__pycache__
│ test_sprite_manager.cpython-37-pytest-5.0.0.pyc
│ test_sprite_manager.cpython-37-PYTEST.pyc
│ test_Texture.cpython-37-pytest-5.0.0.pyc
│ test_Texture.cpython-37-PYTEST.pyc
│
└───__pycache__
OpenGLTestCase.cpython-37.pyc
Sprite.cpython-37.pyc
SpriteManager.cpython-37.pyc
SpriteRenderer.cpython-37.pyc
Texture.cpython-37.pyc
__init__.cpython-37.pyc
The parent folder that holds all of this is called "pygameOpenGLUtil". I have my main 4 files in the highest directory along with my __init__.py. When I try and run pytest at this level it says throws a "ModuleNotFoundError: No module named 'pygameOpenGLUtil'". This thrown in my test_sprite_manager.py file. I've gotten this to work in other projects before but I can't seem to figure out what is wrong with this one I am sure i'm just forgetting something small.
Here is my __init__.py:
from .OpenGLTestCase import *
from .Sprite import *
from .SpriteManager import *
from .SpriteRenderer import *
from .Texture import *
And here is my test_sprite_manager.py:
import pygame
from OpenGL.GL import *
from pygameOpenGLUtil import *
class SpriteManagerTest(OpenGLTestCase):
def test_add_sprite(self):
test_sprite_map = SpriteManager()
test_sprite_one = Sprite(test_sprite_map)
test_sprite_one = Sprite(test_sprite_map)
if __name__ == "__main__":
unittest.main()
I am running python3.7.3 and pytest version 5.0.0
This is my configure file:
The layout.jade does not seem to be working. But the jade is working. I used Chrome to check, and am sure that the layout HTML is not loaded into the page.
module.exports = function(app, express, mongoose){
var config=this
app.configure(function (){
app.set('views',__dirname+'/views')
app.set('view engine','jade')
app.set('view options', {layout:true})
app.use(express.bodyParser())
app.use(express.methodOverride())
app.use(express.cookieParser())
app.use(express.session({secret: 'topsecret',store: new express.session.MemoryStore}))
app.use(express.static(app.path.join(app.application_root,"public")))
app.use(express.errorHandler({dumpExceptions:true,showStack:true}))
app.use(express.bodyParser({keepExtensions: true, uploadDir:"./public/uploads"}))
app.use(app.router)
})
/*DB part:*/
app.mongoose.connect('mongodb://localhost/dio_database')
return config
}
The render command:
app.get('/items/:id',function(req,res){
models.ItemModel.findOne({_id:req.params.id}).exec(function(err,item){
if (!err){
res.render('item.jade',item)
} else
return console.log(err)
})
})
My layout.jade, quite simple:
!!!
doctype 5
html
head
title "Dio"
link(rel='icon', href='favicon.ico', type='image/x-icon')
link(rel='shortcut', href='favicon.ico', type='image/x-icon')
link(rel="shortcut", href="favicon.ico", type="image/vnd.microsoft.icon")
link(rel="icon", href="favicon.ico", type="image/vnd.microsoft.icon")
script(src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js")
script(src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js")
script(src="./javascripts/underscore-min.js")
script(src="./javascripts/backbone-min.js")
link(rel='stylesheet', href='./css/main.css', type="text/css", media="screen")
body
div#topbar Dio--where shitty thing happens
div#main!= body
footer
p
| Node.js MVC template by XXX
And the following is my npm list:
├─┬ bcrypt#0.7.3
│ └── bindings#1.0.0
├─┬ express#3.0.3
│ ├── commander#0.6.1
│ ├─┬ connect#2.7.0
│ │ ├── bytes#0.1.0
│ │ ├── formidable#1.0.11
│ │ ├── pause#0.0.1
│ │ └── qs#0.5.1
│ ├── cookie#0.0.5
│ ├── cookie-signature#0.0.1
│ ├── crc#0.2.0
│ ├── debug#0.7.0
│ ├── fresh#0.1.0
│ ├── methods#0.0.1
│ ├── mkdirp#0.3.3
│ ├── range-parser#0.0.4
│ └─┬ send#0.1.0
│ └── mime#1.2.6
├── fs#0.0.0
├── imagemagick#0.1.3
├─┬ jade#0.27.7
│ ├── coffee-script#1.4.0
│ ├── commander#0.6.1
│ └── mkdirp#0.3.4
├─┬ mongodb#1.2.2
│ └── bson#0.1.5
├─┬ mongoose#3.4.0
│ ├── hooks#0.2.1
│ ├─┬ mongodb#1.1.11
│ │ └── bson#0.1.5
│ ├── ms#0.1.0
│ └── sliced#0.0.3
├─┬ node-static#0.6.5 extraneous
│ ├── colors#0.6.0-1
│ └─┬ optimist#0.3.5
│ └── wordwrap#0.0.2
└── path#0.4.9
Actually the reason for such problem is quite simple:
Express 3 no longer supports layout..But do not be sad. Actually Express 3 begins to adopt a more natural and easier way, which is called block/extends.
The basic usage should be like this:
// In layout file: layout.jade
html
head
title XXX
block scripts
body
block content
block footer
// in a extended file, for example index.jade:
extends layout
block scripts
//write javascript part
block content
// write content
block footer
// write the footer
It actually becomes easier and more flexible. Glad to get it finally. But it took me more than 2 hours.
I am just wondering why so few people mentioned this change more clearly and openly. Hope this post can help some people like me.