Django management command barfs on sites framework

As always, the story is a bit convoluted …

I had recently made changes to the get_absolute_url() methods on a couple of application models (Django 1.3/Python 2.4).  For various reasons, the admin UI for the app is on an intranet site, which is a different host from the public site (represented by a different Django Site object).  The changes involved calling a new function that uses the current site object to determine the appropriate domain for constructing a fully-qualified URL for get_absolute_url().  As originally implemented, I set a variable at the module level in

BASE_PUBLIC_URL = 'http://%s/path/to/app' % get_public_domain()

where get_public_domain() imports the Site model class from django.contrib.sites, calls Site.objects.get_current() and returns the appropriate public domain.  The get_absolute_url() methods then used BASE_PUBLIC_URL in constructing the final URL.

This worked fine in the normal application contexts, i.e., the admin site and the public site.  However, a custom management command which updates app data from an external source raised an ImportError on the relevant model.  The significant part of the traceback was as follows:

  File "/path/to/pyenv/lib/python2.4/site-packages/django/contrib/sites/", line 25, in get_current
    current_site = self.get(pk=sid)

Ad hoc testing showed the ImportError to be a red herring — and, in any case, it didn’t square with the fact that the rest of the app (minus the admin command) was functional.

Now, the management command doesn’t actually call get_absolute_url(), so I figured that maybe the solution was to wrap the base public URL in a memoized function, so that the current site object is accessed lazily:

def get_base_public_url():
    from import get_public_domain
    return 'http://%s/path/to/app' % get_public_domain()

That did the trick.  I’m still not sure exactly why the sites framework barfed, and it doesn’t seem worth digging for …


, ,