2

As I was looking through my settings.py file in my current project, I realized I wasn't too sure what was really going on under the hood with python in terms of os.path.join

I tried looking it up, but its a bit confusing - and seems a bit esoteric when you delve deep.

So lets take the following example:

os.path.join(PROJECT_DIR, 'templates'),

Some points I'd like answered from this example:

1. What exactly is os.path.join doing here? What exactly is being joined?

2.What is PROJECT_DIR? Where was PROJECT_DIR set and how does PROJECT_DIR itself point to the project directory all the time, regardless of its location(on a server, locally, etc)?

Now lets consider this example (which I took from my friend), that makes it the case that when I run on a server(ON_OPENSHIFT seems to be my host) I use a particular static directory:

if ON_OPENSHIFT:
    STATICFILES_DIRS = (
        # Put strings here, like "/home/html/static" or "C:/www/django/static".
        # Always use forward slashes, even on Windows.
        # Don't forget to use absolute paths, not relative paths.


    )
else:
    STATICFILES_DIRS = (
        # Put strings here, like "/home/html/static" or "C:/www/django/static".
        # Always use forward slashes, even on Windows.
        # Don't forget to use absolute paths, not relative paths.
        '/Users/tom/candycode/wsgi/static',

    )

Some questions I'd like answered from this example:

  1. Where is ON_OPENSHIFT defined?

  2. How come on local (the else part of the statement) there seems to be a local directory absolue path, but why not use some type of dynamically ascertained path (like the os.path.join stuff)?

  3. Why does the ON_OPENSHIFT not need to specify a static directory? How does it just "know"? Seems like some type of magic is going on.

ApathyBear
  • 9,057
  • 14
  • 56
  • 90
  • 2
    Assuming that you have already read [the docs for `os.path.join`](https://docs.python.org/2/library/os.path.html#os.path.join), have you tried firing up Python (either IDLE or just a command line REPL) and just doing `from os.path import join` and playing around with it? For example, the following should help a bit: `join('a', 'b', 'c')`, `join('a/b', 'c')`, `join('/a/b/c/d', 'e/f', 'g.ext')`, `join('/a/b/c', '/e/f')`. – Sean Vieira Apr 20 '14 at 02:20
  • I'll scratch that off the list, but my other questions about Django path structure still stand. – ApathyBear Apr 20 '14 at 02:27

1 Answers1

5

Why use os.path.join():

Using os.path.join() (and other os.path functions) help to avoid setting hardcoded paths in your Django project. This way your project can be run on a different computer with a different directory structure without recoding everything. On your computer, the path may be "C:/ApathyBear/Django/mydjango" while on my computer it'll be "Users/Alex/django"

Django settings.py and the PROJECT_DIR

The way it is usually set in a Django project is through the PROJECT_DIR setting. This will be something like PROJECT_DIR = os.path.dirname(os.path.dirname(__file__)), which will take the current file (settings.py), return the directory name, then the directory name that contains that directory. It will usually end up in your project root (may vary depending on your specific setup).

Once you have PROJECT_DIR (or BASE_DIR, or whatever you set it as), then it's easiest to set directories off of that. Using os.path.join() combines the items you put it in. Thus, when you put in os.path.join(PROJECT_DIR, 'templates'), as in your example, it will add templates to your PROJECT_DIR. I'm guessing this is the value for the TEMPLATE_DIRS setting, so your project now knows to look in "C:/ApathyBear/Django/mydjango/templates" for your computer or in "Users/Alex/django/templates" on my computer. Read the docs on os.path.join() for more details on how it works, which is really useful when you don't know the OS you'll be running on.

Other questions

1) ON_OPENSHIFT is likely set earlier in the settings.py file. It should be a boolean, thus either True or False. This setting is saying if ON_OPENSHIFT is set to True, then run these settings, otherwise run the other settings.

This is likely called earlier in the settings.py file using an Environment Variable. Thus, on his Openshift machine, he probably has an environment variable "OPENSHIFT" set to True. Then, in his settings.py, he has something like: `ON_OPENSHIFT = os.environ.get('OPENSHIFT', 'False'). This is saying "Get the environment variable for OPENSHIFT. If there is none, then set it to False. Whatever the outcome of this is, set it equal to ON_OPENSHIFT.

2) The local version doesn't need to use an absolute path. That's likely a choice by your friend, though a somewhat odd one.

3) I'm guessing some code is missing. There should be something in the STATICFILES_DIRS for when ON_OPENSHIFT is True. There's no magic; that setting won't work when ON_OPENSHIFT is True.

Community
  • 1
  • 1
Alex
  • 8,321
  • 1
  • 34
  • 30
  • Thank you. In response to #3, I think because in settings.py we also have "STATIC_ROOT = os.path.join(PROJECT_DIR, '..', 'static')" and "STATIC_URL = '/static/'", could that be the case why it would work. I mean in the absence of a directory, will django use this code instead? The code does work, so it must have some type of explanation.. – ApathyBear Apr 20 '14 at 02:54
  • 1
    Where are your static files located? Are they in `projectroot/static` or are they in `static` directories within apps? Also, if your static files are already in your STATIC_ROOT, then it's no problem. Your `STATICFILES_DIRS` just says places to look when you run the `collectstatic` or `findstatic` commands. See [here](https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-STATICFILES_DIRS). It won't affect the actual serving of static files (as long as you're not using the static files serving view). – Alex Apr 20 '14 at 03:00
  • Static files are located in the projectroot/static, not in individual apps. What is the static files serving view? I am a bit confused as to what those do actually. – ApathyBear Apr 20 '14 at 06:31