How do I enter the Django Shell? I am not seeing clear instructions on how to achieve this.
You can run that code interactively in the dev shell.
python manage.py shell
For future reference, though: all you need to do to make a plain .py file "Django compatible" is that you set the DJANGO_SETTINGS_MODULE environment variable before importing any Django stuff:
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproj.settings")
from myapp.models import Stuff
# ...
Related
I am trying to execute an external snippet for debugging and terminal-like purposes in the environment the Django console uses so it can connect to the db, etc.
Basically, I am just using it for the same reason one would fiddle with the console but I am using longer snippets to output some formatted information so it is handy to have that code in an actual file manipulated with an IDE.
An answer said you could do that by executing python manage.py shell < snippet.py but I did not see a successfull result. And although no errors are reported, I am not getting the excepted output, but only a series of >>> prompts.
So how can I do this?
By the way, I am using PyCharm, in case this IDE has a shorthand way of doing this or any special tool.
I would say creating a new Custom management command is the best way to achieve this goal.
But you can run your script in a django environment. I use this sometimes to run a oneoff script or some simple tests.
You have to set the environment variable DJANGO_SETTINGS_MODULE to your settings module and then you have to call django.setup()
I copied these lines from the manage.py script, you have to set the correct settings module!
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings.local")
django.setup()
Here is a simple template script which I use sometimes:
# -*- coding: utf-8 -*-
import os
import django
# you have to set the correct path to you settings module
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings.local")
django.setup()
from project.apps.bla.models import MyModel
def run():
# do the work
m = MyModel.objects.get(pk=1)
if __name__ == '__main__':
run()
It is important to note that all project imports must be placed after calling django.setup().
Many times you need scripts to play with db or more. But you need to the the django way i.e. the ORM and play with every thing that your project has.
You can checkout https://github.com/django-extensions/django-extensions
You create a scripts folder in your project home and write down a method run . the app provide you a way to run those scripts easily.
How to do it.
Step 1 - Install the package.
Step 2 - Create a scripts folder with init.py in project root, and add 'django_extensions' in your applications
Step 3- Create a file send_email_to_users.py in scripts folder. Simple Example.
from project.models import MyModel
from django.contrib.auth.models import User
from project.utils import send_email
def run():
results = MyModel.objects.all()
for res in results:
send_mail(res.email)
Now from command line you can run
python manage.py runscript send_mail_to_users
If its just a one off script,
import django
django.setup()
from myapp.models.import MyModel
You need to have your environmental variable set up, so its easiest to run it from the IDE (make it part of the same project, right click on teh file and there should be a run option).
If you are looking for something to run on a production environment I would create a management command as suggested by DanEEStar.
I am newbee in Django.I finished the Django Tutorial once from the official djangoproject site.Not saying I know everything now, but everything worked perfectly for me till I was referring that website.
I started referring to the Practical Django projects book and somewhere in my models I tried to import :
from django.contrib.auth.models import User
gives me an import error :
ImportError Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined
`
What is really going on here ? I have been successfully importing all the packages till now then why this sudden error ?
How are you running the code that gives you the error? If you are importing the models.py in the shell, use the Django shell command
./manage.py shell
If you are trying the import in another script, you have to set the environment variable DJANGO_SETTINGS_MODULE manually.
import os
if 'DJANGO_SETTINGS_MODULE' not in os.environ:
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
This requires myproject to be in your python path.
See this similar Stack Overflow question for futher discussion.
I'm on Chapter 4: Templates of the Django tutorial, and I'm trying to run the following in an Emacs inferior mode using Python:
>>> from django import template
>>> t = template.Template('My name is {{ name }}.')
>>> c = template.Context({'name': 'Adrian'})
>>> print t.render(c)
My name is Adrian.
>>> c = template.Context({'name': 'Fred'})
>>> print t.render(c)
My name is Fred.
But I get the error here.
A quick search suggests that I should do be setting my DJANGO_SETTINGS_MODULE like so:
>>> import os
>>> os.environ["DJANGO_SETTINGS_MODULE"] = "settings.py"
However, I run into this error:
ImportError: Could not import settings 'settings.py' (Is it on sys.path?): No module named settings.py
I'm using Fedora 16. How do I correctly resolve this problem?
You can do this in the python manage.py shell, since that would have settings.py in . directory.
Otherwise:
Consider settings.py just another python library and you need to ensure its added to sys.path and then you can do as follows :
import settings
from django.core.management import setup_environ
setup_environ(settings) # Setting up the env settings
This sets up the settings to your environment. [ This is the right way ]
There is no secret recipe in settings.py and since django in itself is a library to python, so it could not be default set any paths to your sys.path unless imported and executed - as I suggested.
You should really use setup_environ as suggested in another answer.
A hint regarding this specific exception: DJANGO_SETTINGS_MODULE is a Python module name, so it may not end with ".py". Usually, this would be your_django_site.settings and the module/directory your_django_site has to be in sys.path.
All Django code not in a project should either be run from the Django REPL, available via ./manage.py shell, or run as a standalone script.
In order to test anything in the shell for Django, you should use the Django shell:
python manage.py shell
This will start up a Python interpreter which will magically have your settings file (and the rest of your project) on the Python path.
(This assumes you have a project already. If not, use django-admin.py startproject my_project_name.)
I'm try to populate data into my db and I'd like to use the django API to do so. I've written a python module that allows me to this very easily.
However, within the django shell (manage.py), it doesn't seem possible to run my "populate.py" file.
Is it possible to run my populate.py from the django shell? Or alternatively, should I instead be running a regular python terminal and importing the necessary django components? Either way, I would greatly appreciate some pointers.
You can also consider using the loaddata command or create your own command
Here is my standard wrapper for running django stuff from the command line. This is also useful if you have cron scripts you want to run.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os, sys
# If this script lives in a child directory of the main project directory
# uncomment the following 2 lines:
#dir_parent = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
#sys.path.insert(0, dir_parent)
from django.core.management import setup_environ
import settings
setup_environ(settings)
from django.db import transaction
# import whatever you like from app.models or whatever
# do random stuff.
# If you are *changing* database records,
# wrap your database code either in:
#transaction.commit_manually
def foo():
... stuff
transaction.commit()
# OR end you script with:
transaction.commit_unless_managed()
Update for comment:
The variable mentioned above is not file, it is __file__ (i.e. 2 underscores file and 2 more underscores). This is always set by the Python interpreter to the full path of the file it occurs in. As the comment says, if this script lives in a child directory of the main directory, the directory-of-the-directory of the filename gives you the directory name of the main project directory, and adding that to sys.path will make sure that all of your imports work correctly. If the script lives in the main directory and you execute it from there, then you don't need to do that.
Try django-extensions it has a runscript command you put in a scripts directory.
Oddly the command seems to be missing from the main documentation but if you google django-extensions runscript you will find examples and documentation.
I created a sub-directory of my Django project called bin where I want to put all command-line run Python scripts. Some of these scripts need to import my Django project settings.py file that is in a parent directory of bin.
How can I import the settings.py file from a sub-directory of the project?
The code that I use in my command-line script to set into the "Django context" of the project is:
from django.core.management import setup_environ
import settings
setup_environ(settings)
This works fine if the script is in the root directory of my project.
I tried the following two hacks to import the settings.py file and then setup the project:
import os
os.chdir("..")
import sys
sys.path = [str(sys.path[0]) + "/../"] + sys.path
The cruel hack can import settings.py, but then I get the error:
project_module = __import__(project_name, {}, {}, [''])
ValueError: Empty module name
I think your approach may be over-complicating something that Django 1.x provides for you. As long as your project is in your python path, you can set the environment variable DJANGO_SETTINGS_MODULE at the top of your script like so:
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
In your command line script where you need to read your settings, simply import the settings module from 'django.conf' as you would do in your application code:
from django.conf import settings
And presto, you have your settings and a Django-enabled environment for your script.
I personally prefer to set my DJANGO_SETTINGS_MODULE using '/usr/bin/env' in a bash script called 'proj_env' so I don't have to repeat it
#!/bin/bash
proj_env="DJANGO_SETTINGS_MODULE=myproject.settings"
/usr/bin/env $proj_env ${*}
With this, now I can run any python script with my Django application in context:
proj_env python -m 'myproject.bin.myscript'
If you use virtualenv, this also gives you a good place to source the activate script.
etc. etc.
This is going one level up from your question, but probably the best solution here is to implement your scripts as custom manage.py (django-admin.py) commands. This gives you all of Django's functionality (including settings) for free with no ugly path-hacking, as well as command-line niceties like options parsing. I've never seen a good reason to write Django-related command-line scripts any other way.
Add the parent directory to your path:
import sys
sys.path.append('../')
import settings
Update from comments:
Don't forget the __init__.py file in
the directory that has your
settings.py – S.Lott
Let's say your project directory is /opt/someProject/`
This has files like:
manage.py
Now you have you may have your sub directory anywhere, does not matter.
Eg. subdirectory could be like:
/opt/someproject/dir1/dir2
Now for you to import your project settings inside /opt/someProject/dir1/dir2
You need to set your PYTHONPATH variable
export PYTHONPATH=/opt/someproject/
Now to import modules from bin
from someproject import bin