14

I'm new to Django and want to use its ORM in my scripts without running whole Django thing. I'm scratching my head how to configure it. Searches on StackOverflow didn't help as answers don't show the full picture.

Therefore, I created a small project:

app.py
manage.py
orm/
  __init__.py
  models.py

manage.py has configuration:

from django.conf import settings    
settings.configure(
    DATABASE_ENGINE = 'mysql',
    DATABASE_NAME = 'db',
    DATABASE_USER = 'admin',
    DATABASE_PASSWORD = '',
    DATABASE_HOST = 'localhost',    
    INSTALLED_APPS = ('orm')
)

models.py:

from django.db import models    
class Label(models.Model):
    name = models.CharField(max_length=50) # required max_length

and finally my main file app.py:

from django.conf import settings    
from django.db import models
from orm.models import *   
\# do database maniupaltions

Though after running app.py I receive an error that: django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

What am I doing wrong?

Nazkter
  • 1,010
  • 1
  • 10
  • 29
NGix
  • 2,384
  • 8
  • 24
  • 38
  • 1
    django has management commands that you can run as scripts without running runserver. read more here: https://docs.djangoproject.com/en/1.11/howto/custom-management-commands/ – Vikash Singh Aug 09 '17 at 16:11
  • Use custom command as @VikashSingh has already mentioned. Another alternative could be https://stackoverflow.com/a/41826771/5616580 – mateuszb Aug 09 '17 at 16:32
  • 1
    You're configuring settings in `manage.py`, but you're running `app.py`. If you're gonna run `app.py` that's where you need to configure them. You also need to call `django.setup()` before using the ORM. – knbk Aug 09 '17 at 18:53
  • @knbk `django.setup()` - I think that's the part i was missing, i made it working, thanks – NGix Aug 10 '17 at 08:54

3 Answers3

17

So your question is :

I want to use Django's ORM in my scripts without running a complete Django application, how to configure it?

I'll share what I did for a project I am currently working on, using Django 2.0.2.

I suggest you create a file SetupDjangoORM.pywith :

import django
from django.conf import settings

settings.configure(
    DATABASES={
        'default': {
            'ENGINE': '<your_engine>',
            'NAME': '<database_name>',
            'HOST': '<hostname_or_ip>',
            'PORT': '<port>',
            'USER': '<user>',
            'PASSWORD': '<super_secret_password>',   
        }
    },
    INSTALLED_APPS=[
        '<your_app>',
    ]
)
django.setup()

You can find this informations in your settings.py file.

Then, you can import this wherever you need :

from . import SetupDjangoORM

And now you are able to use Django Models (ORM) in your scripts.

olinox14
  • 5,652
  • 2
  • 19
  • 36
IvanJijon
  • 441
  • 5
  • 14
  • I moved the `SetupDjangoORM.py` to my well working django folder with the apps inside and ran the script. when I try to call `from . import SetupDjangoORM` i get error `from . import SetupDjangoORM ValueError: Attempted relative import in non-package` – Burcardo Apr 29 '18 at 06:31
  • Did you add `__init__.py` file to the folder containing `SetupDjangoORM.py` ? – IvanJijon Apr 30 '18 at 12:24
8

You can find all the information here

This works for version 3.1 of Django

import django
from django.conf import settings
from myapp import myapp_defaults

settings.configure(default_settings=myapp_defaults, DEBUG=True)
django.setup()

# Now this script or any imported module can use any part of Django it needs.
from myapp import models
MohitC
  • 3,952
  • 1
  • 29
  • 49
avimimoun
  • 613
  • 7
  • 17
4

Here's an updated version, fix was including django.setup() line and some additional settings and includes:

manage.py

import os
import sys
import django
from django.conf import settings

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

INSTALLED_APPS = [
    'orm',
]

DATABASES = {
    'default': {
        'ENGINE' : 'django.db.backends.mysql',
        'NAME' : 'playground',
        'USER' : 'admin',
        'PASSWORD' : 'pasw',
        'HOST' : 'localhost',
    }
}

settings.configure(
    INSTALLED_APPS = INSTALLED_APPS,
    DATABASES = DATABASES,
)

django.setup()

if __name__ == "__main__":
    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)

And app.py:

import manage
from orm.models import Label

if __name__ == '__main__':

    Label.objects.create(name='test')
    print(Label.objects.get(name='test'))

Hope someone will find it useful.

NGix
  • 2,384
  • 8
  • 24
  • 38