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
-~----------~----~----~----~------~----~------~--~---

Reply via email to