Ibrahim Fakih
Ibrahim Fakih

Reputation: 61

Django script to access model objects

My django project is called mybooks, and the app is listings. I am writing a python script which is named searchBooks.py which needs some of the models in the listings app. The searchBooks.py script is in the listings folder (same as the models.py) However, I cannot access the models.

I did what some other users suggest here, including

import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mybooks.settings") from listings.models import books

However, I get ModuleNotFoundError: No module named 'listings'

Should I be changing anything in the settings.py? Or maybe the directory of the searchBooks.py?

Upvotes: 0

Views: 1009

Answers (1)

nigel222
nigel222

Reputation: 8212

You need to write a script that runs in Django context, invoked through manage.py. It's quite easy.

In your app, first create app/management/commands/__init__.py (empty file, you may need to make folders). Then, start by copying this template to app/management/commands/noop.py:

# invoke with ./manage.py noop [--total] 1 2 3 ...
# script in  app/management/noop.py with __init__.py

from django.core.management.base import BaseCommand

class Command( BaseCommand):

    def add_arguments( self, parser):    # parser is Python argparse parser

        parser.add_argument( 'number_list', nargs='+', type=int,
            help='any number of integers to add up',
        )

        parser.add_argument( '--total', action='store_true', default=False,
            help='Print the total as well as the args'
        )

        parser.add_argument( '--file', type=self.infile)

    def handle( self, *args, **options ):

        # print( f'Args: {args}' )    # what are args?

        if options['verbosity'] >= 2:  # inherit default options, including verbosity and help.
                                       # use --help to explore the others
            print( f'Options: {options}' )

        if options['total']:
            total = sum( options['number_list'])
            print( f'Total: {total}' )

        if options['file']:
            print('First line is:')
            print( options['file'].readline() )


    def infile( self, arg):
        return open( arg, 'r')

If you are not familiar with argparse, consult its documntation (it's standard Python, not Django): https://docs.python.org/3/library/argparse.html

Once you have established that it works and you can get six with

./manage.py noop --total 1 2 3

copy it as a starting point to some other name in the same folder, and modify it to perform whatever operations you wish to perform from the command line. You'll start by adding

from listings.models import Whatever, ...

and then modify the handle method to do whatever you want with them, as instructed by whatever options you define.

Django doc: https://docs.djangoproject.com/en/2.1/howto/custom-management-commands/

Upvotes: 1

Related Questions