I don't know why my django app run settings/base.py 2 times. I think it would make my app slow down
In my settings/base.py I printed
print('this is base_dir')
print(BASE_DIR)
output is:
this is base_dir
F:\7.Django\BLOG_PROJECT\src_blog
this is base_dir
F:\7.Django\BLOG_PROJECT\src_blog
This is my settings file:
├── settings
| ├──__init__.py
| ├──base.py
| ├──dev.py
| ├──prod.py
and my settings\__init__.py file contain:
import os
from dotenv import load_dotenv
load_dotenv()
if os.environ['ENV_SETTING'] =='prod':
from .prod import *
else:
from .dev import *
from .base import *
This is probably related to the good old double thread spawning in Django. The way Django is setup it spawns two threads at the start, so one process is there to process requests and the other to watch if you changed any code so it can respawn the first one.
If you print the following in settings.py
import os
print(os.getpid())
You would see that it prints 2 different values. This is a standard django behaviour as far as I know.
Related
I'm learning python and received my first error in line 3:
here is my code:
app.py
import logging.config
from flask import Flask, Blueprint
from platform import settings
app = Flask(__name__)
def main():
app.run(debug=settings.FLASK_DEBUG)
if __name__ == "__main__":
main()
and my file structure is like this:
project_name
|--platform
| |--api
| |--database
| |-- __init__.py
| |-- app.py
| |-- settings.py
|--logging.conf
|--requirements.txt
|--readme.md
|--setup.cfg
i use PyCharm IDE and execute in terminal: python platform\app.py
then i receive this error:
Traceback (most recent call last):
File "platform\app.py", line 4,
in
from platform import settings
ImportError: cannot import name 'settings'
any idea what's wrong here?
here is my settings.py
# Flask settings
FLASK_SERVER_NAME = 'localhost:5000'
FLASK_DEBUG = True # Do not use debug mode in production
# Flask-Restplus settings
RESTPLUS_SWAGGER_UI_DOC_EXPANSION = 'list'
RESTPLUS_VALIDATE = True
RESTPLUS_MASK_SWAGGER = False
RESTPLUS_ERROR_404_HELP = False
# MYSQL settings
MYSQL_DATABASE_URI = 'blablalba'
MYSQL_TRACK_MODIFICATIONS = False
PYMYSQL_CONNECTION = {
'host': '123.456.789.111',
'port': 3306,
'user': 'root',
'passwd': 'password',
'db': 'database'
}
You have a package named platform but you are attempting to execute a script in it. When you do that, the script is going to be run independently, with none of the package information because the script is not imported. To do a proper import and then run as a script, use the -m option:
python -m platform.app
This will import the script from the platform package, set up the dependencies correctly, etc.
Generally, you would want to place your executable script outside your main package for this exact reason. If you modify your folder structure to look like this, the command python app.py should run just fine because platform will be a recognized package:
project_name
|--platform
| |--api
| |--database
| |-- __init__.py
| |-- settings.py
|-- app.py
|--logging.conf
|--requirements.txt
|--readme.md
|--setup.cfg
Finally, as a minor nitpick, if you do decide to keep app.py at the package level rather than the project level, I would recommend using relative imports to get the settings:
from . import settings
You have everything setup fine, my guess is that you are using settings.py as a constants file. so instead of
from platform import settings
try to import the values from the file relatively (since both app.py and settings.py are in the same directory)
from settings import *
and then you can use them like
print(FLASK_SERVER_NAME)
Although this would work fine, but I like to do it a bit differently, so as to not end up scratching my head trying to figure out what constant or function comes from where. Here are my 2 cents
import settings.py as configs # or any variable name you want to use
print(configs.FLASK_SERVER_NAME)
# more understandable as now you know FLASK_SERVER_NAME is coming from configs
You can straight away use import settings instead
I have this python file tasks.py
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DjangoWebProject.settings')
from django.contrib.auth.models import User
from logreg.models import ActivationCode
import datetime
def remove_users():
print 'hello worldddddddddddddddddddddddddddddddddd'
inactive_users = []
activation_codes = ActivationCode.objects.all()
for activation_code in activation_codes:
if datetime.datetime.date(activation_code.key_expires) < datetime.datetime.date(datetime.datetime.now()):
inactive_users.append(activation_code.user_id)
for inactive_user in inactive_users:
User.objects.filter(id=inactive_user).delete()
But this is in the root folder and when i try to execute it, it gives me the following error
File
"C:\Users\deybala1\AppData\Local\Continuum\Anaconda2\lib\site-packages\dj
ango\apps\registry.py", line 124, in check_apps_ready
raise AppRegistryNotReady("Apps aren't loaded yet.") django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
How do i fix this?
If you're creating any script that is using your django project, it is absolutely necessary to set path to settings of your project before any import from django or your project. And you're importing user model from django in 1st line and model from your project in second.
Also, you will need to call django.setup() first.
To fix that, move import os and setting path to django settings to the very beginning of your script, and put django.setup() just after that (with proper import), like this:
# first, set path to project settings
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DjangoWebProject.settings')
import django
django.setup()
# now you can import anything else
from django.contrib.auth.models import User
from logreg.models import ActivationCode
import datetime
def remove_users():
print 'hello worldddddddddddddddddddddddddddddddddd'
inactive_users = []
activation_codes = ActivationCode.objects.all()
for activation_code in activation_codes:
if datetime.datetime.date(activation_code.key_expires) < datetime.datetime.date(datetime.datetime.now()):
inactive_users.append(activation_code.user_id)
for inactive_user in inactive_users:
User.objects.filter(id=inactive_user).delete()
Note that you're trying to add a settings module inside a script that already requires it.
Wouldn't it be easier if you add a specific django command? Thanks to it you'd be able to start your task with python manage.py --settings=<path_to_your_settings>.
Another tip:
Move every django import statement below
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DjangoWebProject.settings')
I have this folder structure for django
settings/dev.py
settings/prod.py
settings/test.py
Then i have common settings in settings/common.py in which i check the ENV variable like
if PROD:
from settings.prod import *
Based on ENV variable each one of them will be active
I want to use something like this in my code
from myapp import settings
rather than
from myapp.settings import dev
This is the method which I follow. Learnt this from the book Two Scoops of Django.
Have a file, such as, settings/common.py which will contain the properties/settings which are common in dev, prod and test environment. (You already have this.)
The other 3 files should:
Import the common settings from the settings/common.py by adding the line from .common import *
And should contain settings for its own corresponding environment.
The manage.py file decides which settings file to import depending on the OS environment variable, DJANGO_SETTINGS_MODULE. So, for test environment the value of DJANGO_SETTINGS_MODULE should be mysite.settings.test
Links for reference:
Django documentation for django-admin utility - Link
Two Scoops of Django sample project - Link
Preserve your settings folder structure and create __init__.py there.
Please, use code below in your settings/__init__.py:
import os
# DJANGO_SERVER_TYPE
# if 1: Production Server
# else if 2: Test Server
# else: Development Server
server_type = os.getenv('DJANGO_SERVER_TYPE')
if server_type==1:
from prod import *
elif server_type==2:
from test import *
else:
from dev import *
Now you can set environment variable called DJANGO_SERVER_TYPE to choose between Production, Test or Development Server and import settings using:
import settings
I'm using Falcon framework. I want that all standalone classes store in their own dirs( class that serve for /module1/ was inside dir /module1/):
/app
./app.py
/modules
/__init__.py
/module1
...
/module2
...
....
In app.py I have initialization of application:
import falcon
# falcon.API instances are callable WSGI apps
app=falcon.API()
My problems:
how I must organize import of modules, that I can access from
module2 to module1?
How I can access to app variable of app.py from /module2:
I need do this code:
module2_mngr = Module2(CONFIG_FILE)
app.add_route('/module2', module2_mngr)
PS:
Sorry for my English
Simple example where I can use different configuration based on api.debug.DEBUG flag:
create some base path: /somepath/my_app/
create the folder sturcture:
/somepath/my_app/api
/somepath/my_app/api/debug
/somepath/my_app/conf
/somepath/my_app/conf/prod
/somepath/my_app/conf/dev
create empty files:
/somepath/my_app/__init__.py
/somepath/my_app/api/__init__.py
/somepath/my_app/conf/prod/__init__.py
/somepath/my_app/conf/dev/__init__.py
Example main.py (/somepath/my_app/main.py):
import api.debug
api.debug.DEBUG = False
import conf
Setup api.debug.DEBUG == False
/somepath/my_app/api/debug/__init__.py:
DEBUG = False
Create simple "router":
If api.debug.DEBUG is True - loads production configuration.
If api.debug.DEBUG is False - loads development configuration.
So we create
/somepath/my_app/conf/__init__.py:
import api.debug
if not api.debug.DEBUG:
from conf.prod import *
else:
from conf.dev import *
While I am working at localhost:8080, when I open interactive console and do some operations, like getting list of Kind etc (address: http://localhost:8080/_ah/admin/interactive) then it gives me this error:
<class 'google.appengine.dist._library.UnacceptableVersionError'>: django 1.2 was requested, but 0.96.4.None is already in use
This errors happened several times, in similar cases. It is stuck until restart localhost by dev_appserver.py
Is this a bug or what I am doing wrong?
Example for what I did at interactive console:
from myapp.models import *
for room in Room.all():
room.update_time = room.create_time
room.put()
Note:
This is my django_bootstrap :
import os
import sys
import logging
import __builtin__
from google.appengine.ext.webapp import util
import pickle
sys.modules['cPicle'] =pickle
logging.getLogger().setLevel(logging.INFO)
sys.path.insert(0, os.path.abspath((os.path.dirname(__file__))))
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from google.appengine.dist import use_library
use_library('django', '1.2')
import django.core.handlers.wsgi
def main():
application = django.core.handlers.wsgi.WSGIHandler()
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
my index.ymal in root folder says:
# AUTOGENERATED
# This index.yaml is automatically updated whenever the dev_appserver
# detects that a new type of query is run. If you want to manage the
# index.yaml file manually, remove the above marker line (the line
# saying "# AUTOGENERATED"). If you want to manage some indexes
# manually, move them above the marker line. The index.yaml file is
# automatically uploaded to the admin console when you next deploy
# your application using appcfg.py.
Thus each time I open http://localhost:8080/_ah/admin/datastore, this file updated: which is still has the same content but timestamp of file on operating system says it is updated.
I think here, As the http://localhost:8080 sees that models.py is not the same then it could load it then can not start django_bootstrap.
However if I first open http://localhost:8080/_ah/admin/datastore and then http://localhost:8080, it works. So this is why sometimes I get error sometimes not: It depends of order urls respective