How to have a Python script for a Django app that accesses models without using the manage.py shell?
You need to setup django environment first:
from your_project import settings
from django.core.management import setup_environ
setup_environ(settings)
At last import your models, everything goes just like django.
why I cannot import models to a python script without using django.setup() first
In short, yes. You are required to call django.setup
if you want to use Django features.
Import django models to custom python script
There is a lot of app configuration done by Django to make your models and settings properly available. The best way to get Django to do this configuration is to make your script a management command, which will be run by python manage.py <your_script_name>
. How to make your own management commands is covered by the docs. https://docs.djangoproject.com/en/3.2/howto/custom-management-commands/
Django 2.0 Access Models (CREATE/REMOVE/FILTER) Standalone [without manage.py shell]
I've once again git clone
'd your Django project's repository and got it working, without having to rework your project's structure, by doing the following:
1. Rework your settings.BASE_DIR
variable
Typically, the file path to a Django project's settings file is projectname/settings.py
but for separated settings it's projectname/settings/<env_name>.py
.
Therefore, BASE_DIR
needs to be reworked from:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
to:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
to account for the extra directory between your project root and your settings file.
2. Change app declaration in INSTALLED_APPS
:
Your app's dotted location from BASE_DIR
is apps.base
. Replace the current declaration, base
, with apps.base
.
3. Fix dotted paths:
If any errors arise from dotted paths, check the traceback as it will point to the issue. For example, your current urls.py
will likely cause an issue because there is a dotted path to base.urls
whereas it should be the explicit apps.base.urls
. For instance:
urlpatterns = [
url(r'', include('base.urls')),
...
]
To the following:
urlpatterns = [
url(r'', include('apps.base.urls')),
...
]
4. Migrate models
Perform ./manage.py makemigrations && ./manage.py migrate
.
Also, as a side-note, migrations
directories shouldn't be in .gitignore
. Read: Should I be adding the Django migration files in the .gitignore file?
And with that I was able to run the below script, at the root of the Django project, without error:
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "DzenanElvir.settings.base")
django.setup()
from apps.base.models import ModelRazred
Accessing django models from a new script
You need is importable settings.
import os
import django
os.environ["DJANGO_SETTINGS_MODULE"] = 'project.settings'
django.setup()
from .models import
Another way call your script via the django shell:
python manage.py shell < script.py
How to execute a Python script from the Django shell?
The <<
part is wrong, use <
instead:
$ ./manage.py shell < myscript.py
You could also do:
$ ./manage.py shell
...
>>> execfile('myscript.py')
For python3 you would need to use
>>> exec(open('myscript.py').read())
Related Topics
No Module Named 'Pandas._Libs.Tslibs.Timedeltas' in Pyinstaller
Convert Timedelta to Total Seconds
Re.Sub Replace with Matched Content
Python: Mocking a Context Manager
Print Statement Inside of Input Returns with a "None"
Smtpauthenticationerror When Sending Mail Using Gmail and Python
Tensorflow: How to Replace or Modify Gradient
How to Make Custom Legend in Matplotlib
How to Escape Latex Code Received Through User Input
How to Remove Item from a Python List in a Loop
Saving Upload in Flask Only Saves to Project Root