Remember to learn to crawl before you can walk. Your first (and even
second and third, most likely) Django application isn't going to be
production quality. Spend some time learning to use Django, then spend
some time looking at options (and there are always options -- no single
best way to do any of this) for splitting up applications and working
with configuration options, etc.
> The first bit I can't figure out are Django applications. I know that
> they are, in essence, Python modules, but it doesn't say what does
> Django do once it encounters an application. Does it add it to the
> sys.path? Does it automatically load certain files, or does that have
> to be explicitly specified somewhere?
Thinking about this as Django "encountering an application" is probably
going to lead to confusion. Django is more of a library than a
framework, from the perspective of somebody writing an application. That
is, you pull things from the Django modules (and your application
modules) as required -- there's relatively little usage of Django
calling something of yours (the exception being the passing of requests
to view functions). The point being that, generally, if you need to use
code from a particular application, you import the appropriate Python
module(s) and use it, just like in normal Python code.
Django certainly doesn't do any modification of sys.path for particular
applications. Quite the reverse: it is assumed that applications are
importable using the name you specify in the INSTALLED_APPS list. That
is, your Python path has to already be set up so that you can import all
those things using those names.
The main reason (from an import perspective) that Django needs to know
about the installed applications (the INSTALLED_APPS list) is so that it
can work out reverse relations automatically. If you specify that model
A in application XYZ has a many-to-one relation to model B in
application PQR, Django will also set things up so that model B can
refer back to model A, without needing to also specify something in the
source for model B. This means that when importing model B, Django needs
to look at all the other models in all the installed applications to see
if there are any field pointing to model B (this is done through some
caching, the computation isn't something onerous on every request).
By and large, though, that last paragraph isn't important. The important
part is the first think I mentioned: if you need to use some code from
an application, import it as per normal.
>
> Another question I have is with custom settings. I'd like to have each
> application have it's own settings file. How is this then accessed by
> the application? Do I have to import /proj/myapp/settings.py in my
> main /proj/settings.py file? I figure that this would make the
> settings globally available, so /proj/myapp2 can access the settings
> from /proj/myapp1, but what if I want to have some application
> specific settings that I do not wish to be accessed by other
> applications too?
Life doesn't really work like that.
Django's "settings" are, intentionally an essentially globally visible
object that anything can read. The reason it's read via a single file is
because there are potentially highly complex interactions between
settings when you're involving multiple applications and we require a
human -- the installing user -- to set things up in an holistic fashion.
At the settings level, it's pretty difficult to remain entirely
orthogonal, due to the intentional global visibility nature of things.
However, if you're just talking about intra-application settings of some
kind that the end-users won't need to touch (making them not really
settings at all), then don't bother user Django's settings
infrastructure. Just put them into a module that you import directly and
access as a normal namespaced Python object.
if these are things that the end-user is meant to configure, then you
should view them as settings an expect/allow them to be configured
however the user wants so that they are ultimately visible in the
settings.py (or whatever the name might be) file that is given to Django
as the module to read the settings from. Django follows Python's
practices here: it's a framework (or language, in Python's case) for
consenting adults. Don't become overly finicky about trying to hide
settings, because you're working at cross-purposes with your users. The
settings aren't meant to be hidden, since they're user configurable.
Other applications aren't going to be wandering the streets at night
looking for randomg settings to co-opt for their own nefarious purposes,
so things can live together in a settings file. The only thing to be
aware of is name clashes...
Use descriptive settings names that are chosen so as to be highly
unlikely to collide with anything else. For example, if your application
was called "xyzzy", you might well specify your settings as
XYZZY_HOST_PATH, XYZZY_ADMIN_NAME, etc, making them self-documenting and
unlikely conflict. Again, the settings are global in visibility, so some
care is needed to avoid namespace clashes, but it's the same care you
have to take to make sure your application name is unique and isn't
particularly onerous.
> Also I was wondering if there was a Pythonic analogue for the
> alternative shorthand conditional syntax '(cond) ? true : false'. I
> wanted to do something like:
>
> DEBUG, DATABASE_USER, DATABASE_PORT = if gethostname='development-
> server' : True, 'dev-user', '1047' else: None, 'prod-user', '3306'
Because you're allergic to readable code? Good grief.
One simple, readable solution here is:
if setting_condition():
DEBUG, DATABASE_USER, DATABASE_POST = True, "dev-user", 1047
else:
DEBUG, DATABASE_USER, DATABASE_POST = False, "prod-user",
3306
Line breaks are your (and readability's) friend. :-)
Alternatively, you could write a function that returns a tuple,
depending on the condition and assign that tuple to the three settings
variables.
Regards,
Malcolm