2

Django 1.11

Python 3.6.1

For my project is to be deployed, I will have to predefine some things. Namely, I'll need a couple of groups for users.

So, I made a directory "deployment" and placed it next to the project's directory.

When a new database will be created, I'll just execute:

python manage.py shell < ../deployment/initialize_project.py

This code works:

from django.contrib.auth.models import Group

Group.objects.create(name="commentator") # Can only comment.

Group.objects.create(name="contributor") # Can add, change and delete
                                         # objects.

This code does not:

from django.contrib.auth.models import Group


def initialize_roles():

    Group.objects.create(name="commentator") # line 6

    Group.objects.create(name="contributor") 


initialize_roles() # line 12

Traceback:

Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "/home/michael/workspace/venv/photoarchive/lib/python3.6/site-packages/django/core/management/__init__.py", line 363, in execute_from_command_line
    utility.execute()
  File "/home/michael/workspace/venv/photoarchive/lib/python3.6/site-packages/django/core/management/__init__.py", line 355, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/michael/workspace/venv/photoarchive/lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/michael/workspace/venv/photoarchive/lib/python3.6/site-packages/django/core/management/base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "/home/michael/workspace/venv/photoarchive/lib/python3.6/site-packages/django/core/management/commands/shell.py", line 101, in handle
    exec(sys.stdin.read())
  File "<string>", line 12, in <module>
  File "<string>", line 6, in initialize_roles
NameError: name 'Group' is not defined

I marked line 6 and 12 in the code above (as inline comments).

I tried to use pdb.set_trace(), but the same error appear. As if pdb is not defined.

I also tried not to feed manage.py on initialize_project.py, but just run python manage.py shell and feed the code line by line. It worked perfectly.

Could you give me a kick here?

ADDED LATER

This works:

def initialize_roles():
    from django.contrib.auth.models import Group
    Group.objects.create(name="commentator") # Can only comment.

    Group.objects.create(name="contributor") # Can add, change and delete
                                             # objects.

initialize_roles()
Michael
  • 4,273
  • 3
  • 40
  • 69
  • 1
    There's clearly something going on in the lines you've edited out. Do you redefine Group inside that function, by any chance? – Daniel Roseman Apr 11 '17 at 15:14
  • No redefinition inside that function. I would say - to the best of my ability - that those lines are exactly as I give them here. I just copied them. In the whole file there is nothing else but a comment for the function. – Michael Apr 11 '17 at 15:18
  • Interesting! Does this work when manually copy-pasted the code in `python manage.py shell` . Imean `initialize_roles()` style which is not working – rrmerugu Apr 11 '17 at 15:25
  • Being manually copied to the shell line by line, it works perfectly. – Michael Apr 11 '17 at 15:31
  • Why do you added the import inside the function? – Elias Prado May 24 '21 at 14:54

2 Answers2

0

Unless there is more to what you're doing, this feels like something fixtures are meant to solve. If there is more to it, you can add custom data migrations as part of the initial set up process. That will avoid having to worry about when models are available to you.

Tom
  • 22,301
  • 5
  • 63
  • 96
  • Tom, the question was not about fixtures. This is strange behaviour of a python program, isn't it? – Michael Apr 11 '17 at 15:46
0

I faced similar situation - this behavior is strange, indeed. It looks like inside this function, all the imports are missing (I checked that with dir() - it was empty), but I don't know why. Would be great if someone could answer that.

I don't think it's elegant to keep the script unwrapped by function, and as I was facing the same thing, I found this thread useful (danodonovan's answer): Python Script from Django shell. What he suggests is to create commands subdir, and add a script to it (for instance init_db). Then you can easily run:

./manage.py init_db

This resolves problems stated in your question, but not answers why is it happening. I hope that someone explain that.

Dawid Gacek
  • 544
  • 3
  • 19