NGix
NGix

Reputation: 2662

Use Django ORM outside of Django

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?

Upvotes: 20

Views: 12422

Answers (4)

Harsh Bhikadia
Harsh Bhikadia

Reputation: 10875

You can do it with dorm.

DISCLAIMER: I am the maintainer of the package

After installation pip install dorm-project you simply need to add settings.py to the project root with atleast INSTALLED_APPS and DATABASES values

# <proj-root>/settings.py
from pathlib import Path

BASE_DIR = Path(__file__).parent.resolve()

INSTALLED_APPS = []
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": BASE_DIR / "db.sqlite3",
    }
}

Ensure that you call dorm.setup() in your projects endpoints to make sure the ORM is ready to use.

import dorm

if __name__ == "__main__":
    dorm.setup()

With that you can start adding your models to models.py files inside any package (known as apps in django, don't forget to add the package to INSTALLED_APPS in settings.py file) - just like how you would do it in a "full" django project.

# blog/models.py
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(unique=True)
    body = models.TextField()
# <proj-root>/settings.py
INSTALLED_APPS = ["blog"]

All Django management commands like makemigrations, migrate, shell, test, etc can be run using dorm cli

dorm makemigartions
dorm migrate

You can all add unittests that can use the ORM, and run with Django Test Runner:

# blog/tests.py
from django.test import TestCase

from blog.models import Post


class TestPostModel(TestCase):
    def test_creating_object(self):
        post = Post()
        post.title = "Fake title"
        post.slug = "fake-title"
        post.post = "fake body"
        post.save()
dorm test
...
Found 1 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

Upvotes: 0

avimimoun
avimimoun

Reputation: 951

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

Upvotes: 10

IvanJijon
IvanJijon

Reputation: 447

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.

Upvotes: 21

NGix
NGix

Reputation: 2662

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.

Upvotes: 7

Related Questions