Pratik Khadloya
Pratik Khadloya

Reputation: 12869

Django model outside of django

I have a non django project for which i would like to use the django models for data access layer.

Added the models lib in requirements.txt
django-model-utils==3.1.1

And code set it up like below:

from django.conf import settings
from django.db import models

settings.configure(
  DATABASE_ENGINE='django.db.backends.mysql',
  DATABASE_NAME='***',
  DATABASE_USER='***',
  DATABASE_PASSWORD='***',
  DATABASE_HOST='***',
  DATABASE_PORT='***')

class Bus(models.Model):
  class Meta:
    db_table = 'my_custom_bus'

  bus_name = models.CharField(max_length=20)
  bus_description = models.CharField(max_length=100)

But when i ran the above code, i am getting the following error: django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

In order to fix the above error, i ran:

import django  
django.setup()

Now when i try, i get:
Bus doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS

Am i missing some setting here or is there any light weight model only lib in python?

Upvotes: 8

Views: 3825

Answers (2)

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 run dorm init inside the project root OR manually create 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

Reza Torkaman Ahmadi
Reza Torkaman Ahmadi

Reputation: 3038

(It's an old question, but i answer it, maybe help others.)

option 1 (recommended)

seeing comments, you mentions:

In my particular case, wherein its simply a set of scripts downloading data from apis and saving in database, sqlalchemy is suiting well.

In some situations (like what you mentioned) you can use django management commands. For example if you want to do some tasks that are related to django models and should run in background. like some crontab jobs like updating database fields every 5 minutes or executing some script related to some apis that should run and update database models.

For this, create a management command like below and your good to go:

  • in your app, create a folder management. then add an empty __init__.py file to it. next create another folder called commands in that folder and yet add another empty __init__.py to commands folder. now create your script files in commands folder. for example test_script.py.

  • Now add this in test_script.py:

    from django.core.management.base import BaseCommand
    
    class Command(BaseCommand):
    
        def handle(self, *args, **kwargs):
            # Add your script codes here.
    
  • Now to run it, simply execute this command: python manage.py test_command

  • for more details read this link

option 2

There is a powerful ORM for python sqlalchemy. You can use it if you don't want to use any part of django or create another django and add your non-django project's code to it. But remember you need to define your django model design with sqlalchemy too. But it's not that hard to do that.

option 3

as my friends suggested in comments, you can config another project to use your existing django project as an app. follow Using Django database layer outside of Django?

Upvotes: 1

Related Questions