1

I want to use a Django model in an external python script. This python script is placed within the root directory of my project and I also created an init.py module for easy importing. Can anyone please instruct on what is the most secure and efficient way of importing a Django model into the python script?

I would also appreciate it if someone could advise me whether or not it is accurate to place an init.py module within the root directory. If not, what is the best way of doing this?

jelly_bean
  • 89
  • 1
  • 1
  • 7

1 Answers1

1

use this solution only if you want your scripts to be standalone (you want to access models when server is not running)

There are basically two different ways to do that:

  1. If you are going to run this code frequently, I strongly suggest that you create a management command for the code. (check instructions here)

  2. But if it's a bulk-data-import or something that's not gonna run many times, you can use something like this (put this in the root of your django app - beside manage.py):

import os
import django

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "<your_project_name>.settings")
    django.setup()

    # now you have access to your models
    # as an example:

    # from users.models import User
    # 
    # for user in User.objects.all():
    #     print(user)

also keep in mind that you should always import your models after django.setup(), otherwise, you'll get an error.

I would also appreciate it if someone could advise me whether or not it is accurate to place an init.py module within the root directory. If not, what is the best way of doing this?

If you want to have multiple script files, it's not a good idea to put them in the root of django project. You can create a python package, say my_scripts, beside manage.py and put your scripts there.

So you will end up with something like this:

...
manage.py
my_scripts
├── __init__.py
└── first_script.py

But now you need to make a little change in the script file to make it work correctly. You should append the BASE_DIR to your path so that python can recognize the settings file (or module, if you extend it):

import os
import sys
import django

if __name__ == '__main__':
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(BASE_DIR)
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "<your_project_name>.settings")
    django.setup()

    # now you have access to your models
    # as an example:

    # from users.models import User
    #
    # for user in User.objects.all():
    #     print(user)
Pedram Parsian
  • 3,750
  • 3
  • 19
  • 34
  • Regarding the first option, I wish to call the external python script as a function in my views.py module after clicking a button using AJAX in my template. If I give a management command to it, won't the process be **less dynamic**? I'm looking for a dynamic way that lets me call a python script which uses a Django model in my project. It's what I have in mind but in your perspective, is it okay to use a management command for this? – jelly_bean Nov 09 '19 at 16:28
  • If you want to use these scripts **while django is running**, then you don't need these solutions. You can simply create python file, say `utilities.py`, beside your desired app, and you can normally import _any_ of your models from there. I thought you want your scripts to be **standalone** (so that you can run them even if the server is not running). See [this](https://stackoverflow.com/questions/3295268/where-should-utility-functions-live-in-django) – Pedram Parsian Nov 09 '19 at 16:45
  • Oh yes, that's what I am looking for. The script should be present beside manage.py right? Along with the script, I got a couple of other python modules in a folder as well. I can place them in the root directory of my project right? – jelly_bean Nov 09 '19 at 16:54
  • Yes, that's it. You can put the script itself in one of your _apps_ directory, if it is related to just one specific app, or, as you said, put it beside `manage.py`. – Pedram Parsian Nov 09 '19 at 17:06
  • That's cool. Thanks for your time. So, just to clarify once more, I don't need to follow the above steps right? (since I wish to run scripts while the server is running...) – jelly_bean Nov 09 '19 at 17:09