On Sat, 2009-05-02 at 09:09 -0700, Jeff wrote: > I'm using Django's authentication. I would like to add several users > through a command-line script (not through code executed via the > website). Something like manage.py createsuperuser but for normal > users and not interactive. I want to be able to put code like this in > a script I can run offline like manage.py: > > >>> from django.contrib.auth.models import User > >>> User.objects.create_user('john', 'len...@thebeatles.com', 'johnpassword') > > ...but I don't know what needs to go above that code to set up the > environment to make it work. I've started looking into how manage.py > works, but I'm getting lost in Django internals. I'd rather not > fiddle with the database manually, since I'm not sure I know > everything I'd need to touch to keep it consistent. > > Any ideas? How do I set up the environment of a Django app offline, > in a simple command line script so that Users (or other parts of the > db) can be modified without running through a web server?
There are a couple of different solutions to this problem. Ultimately, it comes down to providing the necessary information so that Django can use your settings to determine the database name and backend and things like that. Here are a few possibilities: (1) To my mind, the hackiest approach here is to call django.core.management.setup_environ() and pass it the right things (it's in django/core/management/__init__.py). Have a look at how Django itself calls it in __init__.py -- it's only called in a couple of places. I dislike what setup_environ() does to sys.path, adding in something extra, but it's definitely the closest to what manage.py does, since it's called as part of running manage.py. (2) Fortunately, if you want to behave like manage.py, there's an easier, more explicit approach. When you have "from django.conf import settings" in your Python code, Django will use the DJANGO_SETTINGS_MODULE environment variable to work out what module to import. So you can set that directly in the environment before doing anything that involves using Django itself: import os os.environ["DJANGO_SETTINGS_MODULE"] = "foo.bar.settings" ... # Now do stuff involving Django, such as using the ORM The string you assign to the environment variable here is something importable (i.e. on the Python path). You could even use Python's optparse module to process command line arguments and accept a "--settings" option and use that as the thing to set. (3) You could be Old Skool. Set the environment variable in the process that calls your Django-using script. That means you won't need the os.environ bit in the above fragment. I often use this when writing little scripts. Calling them might look something like this: DJANGO_SETTINGS_MODULE="test.settings" PYTHONPATH=/home/malcolm/CIA_factbook ./process_imports.py (that's all on one line and is taken directly from my bash history). The process_imports.py script here doesn't do anything special. It just uses Django and whenever settings are needed, the environment variable is set and so importing the right settings file Just Works(tm). (4) Finally, the cleanest solution from a coding point of view is manual configuration. This is specifically designed for using Django inside other frameworks or larger applications. You call the configure() method in the settings module and pass in only the settings you need: from django.conf import settings from django.contrib.auth import models ... my_settings = { "DATABASE_ENGINE": "postgresql_psycopg2", "DATABASE_NAME": "secret_project", ... } settings.configure(**my_settings) This is documented, to some extent: http://docs.djangoproject.com/en/dev/topics/settings/#using-settings-without-setting-django-settings-module What isn't document is which settings are needed if, for example, you're only going to use the ORM portion, or only the template engine. That's a been a "todo" item for about three years now. One day, it might even be done. That being said, common-sense and a bit of experimentation goes a long way. If you're using the ORM, you need a bunch of the database-related settings and probably not much else. Then test and make sure things work. Tweak appropriately. Hopefully the above give you a few options. In my own code, both personally and professionally, I use options (3) and (4) in different situations. Option (3) is faster to get up and running and is pretty clear if you have experience in Unix-like situations. Option (4) is nicer if Django is a library being used with lots of other stuff, but can be fiddlier to set up initially. Regards, Malcolm --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---