Terminal says that i didn't defined DJANGO_SETTINGS_MODULE but i tried as i thought every method to do it and so far nothing helper (coding on windows)
Can someone help me out please? I am stuck and dont know what to do
Maby this will help - i run my virtual env through Anaconda -
conda activate djangoenv
raise ImproperlyConfigured(django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
from faker import Faker
from app.models import AccessRecrod, Webpage, Topic
import random
import django
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
django.setup()
fakegen = Faker()
topics = ['Search', 'Social', 'Marketplace', 'News', 'Games']
def add_topic():
t = Topic.objects.get_or_create(top_name=random.choice(topics))[0]
t.save()
return t
def populate(N=5):
for entry in range(N):
# get topic for entry
top = add_topic()
# create fake data for entry
fake_url = fakegen.url()
fake_date = fakegen.date()
fake_name = fakegen.company()
# create new webpage entry
webpg = Webpage.objects.get_or_create(
topic=top, url=fake_url, name=fake_name)[0]
# create fake access record
acc_rec = AccessRecrod.objects.get_or_create(
name=webpg, date=fake_date)[0]
if __name__ == '__main__':
print('populating script!')
populate(20)
print('populating complete!')
The Problem is simply your import of models. You just need to setup django before you import anything related to django:
import django
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
django.setup()
from faker import Faker
from app.models import AccessRecrod, Webpage, Topic
import random
rest of your code
If you check the code in manage.py and django code on github you will essentially find the same sequence of code (besides a lot of additional stuff) when you run a management command by "python manage.py your_command"
To use the management command directly as described in the answer from #Code-Apprentice would be the other "normal" or "more django way" to integrate your script.
But you asked for the reason of the error message in your way of doing it.
If you study the complete error trace you will also find that it starts at the import command.
Instead of trying to shoe horn a regular python script into the Django environment like this, I suggest you create a command which you can run with ./manage.py. You can learn how to create your own custom commands here. When you do this correctly, you can run a command like ./manage.py create_topics or whatever name you give your command. This allows manage.py to load the Django environment for you.
Alternatively, you could look at creating fixtures with ./manage.py dumpdata and ./manage.py loaddata. These commands will allow you to create data and save them to a .json file which you can load into your database at any time.
Related
We are using Django as backend for a website that provides various things, among others using a Neural Network using Tensorflow to answer to certain requests.
For that, we created an AppConfig and added loading of this app config to the INSTALLED_APPS in Django's settings.py. This AppConfig then loads the Neural Network as soon as it is initialized:
settings.py:
INSTALLED_APPS = [
...
'bert_app.apps.BertAppConfig',
]
.../bert_apps/app.py:
class BertAppConfig(AppConfig):
name = 'bert_app'
if 'bert_app.apps.BertAppConfig' in settings.INSTALLED_APPS:
predictor = BertPredictor() #loads the ANN.
Now while that works and does what it should, the ANN is now loaded for every single command run through manage.py. While we of course want it to be executed if you call manage.py runserver, we don't want it to be run for manage.py migrate, or manage.py help and all other commands.
I am generally not sure if this is the proper way how to load an ANN for a Django-Backend in general, so does anybody have any tips how to do this properly? I can imagine that loading the model on startup is not quite best practice, and I am very open to suggestions on how to do that properly instead.
However, there is also some other code besides the actual model-loading that also takes a few seconds and that is definitely supposed to be executed as soon as the server starts up (so on manage.py runserver), but also not on manage.py help (as it takes a few seconds as well), so is there some quick fix for how to tell Django to execute it only on runserver and not for its other commands?
I had a similar problem, solved it with checking argv.
class SomeAppConfig(AppConfig):
def ready(self, *args, **kwargs):
is_manage_py = any(arg.casefold().endswith("manage.py") for arg in sys.argv)
is_runserver = any(arg.casefold() == "runserver" for arg in sys.argv)
if (is_manage_py and is_runserver) or (not is_manage_py):
init_your_thing_here()
Now a bit closer to the if not is_manage_py part: in production you run your web server with uwsgi/uvicorn/..., which is still a web server, except it's not run with manage.py. Most likely, it's the only thing that you will ever run without manage.py
Use AppConfig.ready() - it's intended for it:
Subclasses can override this method to perform initialization tasks such as registering signals. It is called as soon as the registry is fully populated. - [django documentation]
To get your AppConfig back, use:
from django.apps import apps
apps.get_app_config(app_name)
# apps.get_app_configs() # all
This is another way, in your manage.py will have something probably look like this
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'slambook.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
# check if has runserver
if `runserver` in sys.argv:
#execute your custom function
if __name__ == '__main__':
main()
you can check sys.argv if it have runserver, if so then execute your script or function
I installed Django on Windows 10, Django Version 3, Python 3.8 from Conda, with env, on VS Code
My Django works fine without any problem and my App and Project also works fine, but I decided to use Faker to generate some fake data in my DB, I have to mention that my Model works and connected successfully to my DB and migration process was successful without any problem.
I write this Standalone app for Faker to run it whenever I need manually:
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'first_project.settings')
import django
django.setup()
# Implement Fake Population script here.
import random
from first_app.models import AccessRecord, Topic, Webpage
from faker import Faker
fakegen = Faker()
topics = ['Search', 'Social', 'Marketplace', 'News', 'Games']
def add_topic():
t = Topic.objects.get_or_create(top_name=random.choice(topics))[0]
t.save()
return t
def populate(N=5):
for entry in range (N):
# Get the topic for the entry
top = add_topic()
# Create the fake data for that entry
fake_url = fakegen.url()
fake_date = fakegen.date()
fake_name = fakegen.company()
# Create the new webpage entry
webpg = Webpage.objects.get_or_create(topic=top,url=fake_url, name=fake_name)[0]
# Create a fake access record for that webpage
acc_rec = AccessRecord.objects.get_or_create(name=webpg,date=fake_date)[0]
if __name__ == "__main__":
print('Population Script!')
populate(20)
print('Population Completed!')
But whenever I run this code, I get this error:
> (myDjangoEnv) C:\my_path\first-project
> C:/Users/HPTav/anaconda3/python.exe
> c:/my_path/first_project/populate_first_app.py
Traceback (most recent call last):
File "c:/my_path/first_project/populate_first_app.py", line 4, in
<module>
import django
ModuleNotFoundError: No module named 'django'
> (myDjangoEnv) C:\my_path\first-project>
I replaced the path with my_path to make it easier for you when you read the console error.
This is my Django project structure:
I am sure I have Django, as I said my Django app and project works fine.
I checked it by this way to make sure I have Django on this folder:
This project is available in GitHub:
https://github.com/hptavakoli/django_first_app
Sounds like you don't have django installed, install it using this command:
pip install django
In your Command prompt.
Visit this site for additional info: Installing django using pip
What you can do is this:
"Add 'python' while calling populate_first_app.py in the terminal."
python populate_first_app.py
I have a python file called my_functions.py in which I have the following code:
from core.models import Blog
def news():
b = Blog(name='New Blog', tagline='All the latest news.')
b.save()
My main app folder in django is called core and I have put my python file in there. In the shell I am able to do the import: from core import my_functions
However I get an error AttributeError: module 'core.my_functions' has no attribute 'news' when I try to run the code my_functions.news().
How can I run the news function in the shell?
My tree structure is as follows:
core
-__init__.py
-admin.py
-apps.py
-models.py
-my_functions.py
-tests.py
-urls.py
-views.py
Everthing else works as normal but I just cant seem to figure why I cant do this simple import and run the function. I'm using VSCode.
Make sure there's an __init__.py file in the core directory. Then:
from core.my_functions import news
Also you have to restart your shell if you make changes to any file in your project, since the django shell will load all modules in memory at launch time.
Create your file and write your function. In my case was:
# /home/$(USER)/repos/bo/apps/base/queries.py
# "apps.base", added to INSTALLED_APPS list in settings.py
from apps.base.models import Player
from core.models import Blog
def news():
b = Blog(name='New Blog', tagline='All the latest news.')
b.save()
return b
def count_player_overs():
all_playerovers = Player.objects.all()
count_all_playerovers = all_playerovers.count()
return count_all_playerovers
print('count_all_playerovers: {}'.format(count_player_overs()))
print('saved news object: {}'.format(news()))
# this folder has manage.py
cd /home/$(USER)/repos/bo/
And run:
./manage.py shell -c "from apps.base import queries;"
Result:
count_all_playerovers: 376
saved news object: New Blog
You can change the code and run again ./manage.py shell -c "from apps.base import queries;" and it will re-import the module and run the function with all your changes.
Python: 2.7; Django: 1.7; Mac 10.9.4
I'm following the tutorial of Tango with Django
At Chapter 5, the tutorial teaches how to create a population script, which can automatically create some data for the database for the ease of development.
I created a populate_rango.py at the same level of manage.py.
Here's the populate_rango.py:
import os
def populate():
python_cat = add_cat('Python')
add_page(
cat=python_cat,
title="Official Python Tutorial",
url="http://docs.python.org/2/tutorial/"
)
add_page(
cat=python_cat,
title="How to Think like a Computer Scientist",
url="http://www.greenteapress.com/thinkpython/"
)
add_page(
cat=python_cat,
title="Learn Python in 10 Minutes",
url="http://www.korokithakis.net/tutorials/python/"
)
django_cat = add_cat("Django")
add_page(
cat=django_cat,
title="Official Django Tutorial",
url="https://docs.djangoproject.com/en/1.5/intro/tutorial01/"
)
add_page(
cat=django_cat,
title="Django Rocks",
url="http://www.djangorocks.com/"
)
add_page(
cat=django_cat,
title="How to Tango with Django",
url="http://www.tangowithdjango.com/"
)
frame_cat = add_cat("Other Frameworks")
add_page(
cat=frame_cat,
title="Bottle",
url="http://bottlepy.org/docs/dev/"
)
add_page(
cat=frame_cat,
title="Flask",
url="http://flask.pocoo.org"
)
for c in Category.objects.all():
for p in Page.objects.filter(category=c):
print "- {0} - {1}".format(str(c), str(p))
def add_page(cat, title, url, views=0):
p = Page.objects.get_or_create(category=cat, title=title, url=url, views=views)[0]
return p
def add_cat(name):
c = Category.objects.get_or_create(name=name)[0]
return c
if __name__ == '__main__':
print "Starting Rango population script..."
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tangle.settings')
from rango.models import Category, Page
populate()
Then I run python populate_rango.py at the terminal at the level of manage.py, AppRegistryNotReady() is raised:
django.core.exceptions.AppRegistryNotReady
Then I googled it, found something like this:
Standalone scripts¶
If you’re using Django in a plain Python script — rather than a management command — and you rely on the DJANGO_SETTINGS_MODULE environment variable, you must now explicitly initialize Django at the beginning of your script with:
>>> import django
>>> django.setup()
Otherwise, you will hit an AppRegistryNotReady exception.
And I still have no idea what should I do, can some one help? Thx!!!
If you are using your django project applications in standalone scripts, in other words, without using manage.py - you need to manually call django.setup() first - it would configure the logging and, what is important - populate apps registry.
Quote from Initialization process docs:
setup()
This function is called automatically:
When running an HTTP server via Django’s WSGI support.
When invoking a
management command.
It must be called explicitly in other cases, for
instance in plain Python scripts.
In your case, you need to call setup() manually:
if __name__ == '__main__':
print "Starting Rango population script..."
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tangle.settings')
import django
django.setup()
populate()
Also, this problem is described in detail in Troubleshooting section.
I found this solution, adding
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
after
os.environ.setdefault ...
I just stumbled about the same problem in my local development server.
After pulling some changed code in, the error was thrown.
The problem here obviously has nothing to do with wsgi, so I tried to run manage.py
A simple: python manage.py reveals the real error cause.
In my case a forgotten import of an external Django app.
Maybe this helps someone else out.
I also encountered this problem using Django 1.7 on an Apache server. Changing the wsgi handler call in my wsgi.py file fixed the problem:
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
This was suggested here by user 'jezdez'.
I want to run a python scripts which should do:
Create a django project: django-admin startproject foobar
Create a app in the project: python manage.py barfoo
Add an entry of newly created app barfoo in the setting's INSTALLED_APP.
How can I achieve this?
There seems to be a pythonic way to do #1 and #2
https://docs.djangoproject.com/en/dev/ref/django-admin/#running-management-commands-from-your-code
from django.core import management
management.call_command('flush', verbosity=0, interactive=False)
management.call_command('loaddata', 'test_data', verbosity=0)
6 years later I stumbled upon this question trying to figure out how to write some tests for an app which only add a custom template tag that interact with other apps in the project. Hope this can help someone.
Building on #groovehunter answer: the official documentation now (Django 1.10) inculdes this feature outside dev.
Note that you need to change current directory to the created project before call startapp. See this answer for more details
from django.core import management
import os
management.call_command('startproject', 'foobar')
os.chdir('foobar')
management.call_command('startapp', 'barfoo')
or you can use the additional argumento to startproject to create the project in the current directory, if you're sure there won't be problems:
from django.core import management
management.call_command('startproject', 'foobar', '.')
management.call_command('startapp', 'barfoo')
Read a little abour subprocess and Popen method. This might be what you're looking for.
Popen(["django-admin", "startproject", "%s" % your_name ], stdout=PIPE).communicate()
Popen(["python", "manage.py", "%s" % your_app_name ], stdout=PIPE).communicate()
3.
I know that's not a perfect code, but I'm just giving an idea.
with open("settings.py", 'r') as file:
settings = file.readlines()
new_settings = []
for line in settings:
if "INSTALLED APPS" in line:
new_settings.append(line.replace("INSTALLED_APPS = (", "INSTALLED_APPS = (\n'%s'," % your_app_name))
else:
new_settings.append(line)
with open("settings.py", 'w') as file:
file.write("".join(new_settings))