3

I am new to Django, and I'm trying to import one of my models in a script as we do it in views.py. I'm getting an error:

Traceback (most recent call last):

  File "CallCenter\make_call.py", line 3, in <module>

    from .models import Campaign


ModuleNotFoundError: No module named '__main__.models'; '__main__' is not a package

My file structure is like:

MyApp\CallCenter\

CallCenter contains __init__.py, make_call.py, models.py, views.py and MyApp has manage.py

from twilio.rest import Client
from twilio.twiml.voice_response import VoiceResponse, Say, Dial, Number, VoiceResponse
from .models import Campaign


def create_xml():

    # Creates XML
    response = VoiceResponse()
    campaign = Campaign.objects.get(pk=1)
    response.say(campaign.campaign_text)

    return response


xml = create_xml()
print(xml)
3
  • How are you invoking make_call.py? python make_call.py within the CallCenter app directory won't work. Commented Oct 8, 2019 at 13:03
  • @AKX I ran (venv) C:\Users\Username\PycharmProjects\MyApp>python CallCenter\make_call.py Commented Oct 8, 2019 at 13:06
  • 1
    You can't just run a python file inside a Django project as if it were any python script: There's a whole setup Django does to load your apps and models (django.setup()) which is required to be able to use your models etc... If you want to run a command-line like script using Django, create a management command so you can run it with manage.py which will do the proper setup for you. Commented Oct 8, 2019 at 13:08

1 Answer 1

5

In general, it's better to refactor "ad-hoc" scripts – anything you might run manually from a command line, say – into management commands.

That way the Django runtime is set up correctly once things get to your code, and you get command-line parsing for free too.

Your make_call.py might become something like this:

CallCenter/management/commands/make_call.py

from twilio.rest import Client
from twilio.twiml.voice_response import VoiceResponse, Say, Dial, Number, VoiceResponse
from CallCenter.models import Campaign

from django.core.management import BaseCommand


def create_xml(campaign):
    # Creates XML
    response = VoiceResponse()
    response.say(campaign.campaign_text)
    return response


class Command(BaseCommand):
    def add_arguments(self, parser):
        parser.add_argument("--campaign-id", required=True, type=int)

    def handle(self, campaign_id, **options):
        campaign = Campaign.objects.get(pk=campaign_id)
        xml = create_xml(campaign)
        print(xml)

and it would be invoked with

$ python manage.py make_call --campaign-id=1

from wherever your manage.py is.

(Remember to have an __init__.py file in both the management/ and the management/commands/ folders.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.