Javascript with Django?

19,873

Solution 1

But does that /media/ global directory exist? And have you placed in there a scripts subdirectories with the scripts you want to serve from there? What about the /scripts/... url from which you want to serve JQuery.js -- that doesn't seem to be served anywhere from your urls.py. If you (for whatever reason) want to serve scripts (or any other statically served file) from several different URL paths, all of those URL paths need to be matched in urls.py with the static-serving -- or else, do the normal things and serve them all from the /media/... root URL, and map that media root to the dir where you actually keep these files (in their respective subdirs, typically).

Django's docs about static serving (for development only, since it's documented as

Using this method is inefficient and insecure. Do not use this in a production setting. Use this only for development.

so beware!-) seems pretty clear to me.

Solution 2

You may want to use absolute path for 'document_root' in urls.py if you want to use the development server to serve static files. MEDIA_ROOT and MEDIA_URL don't play any role here.

Here are my settings for your reference. I put all static media files under site_media/

mysite/
    site_media/
        css/
        js/
        images/
    ...

in settings.py:

ROOT_PATH = os.path.normpath(os.path.dirname(__file__))

in urls.py:

url(r'^media/(?P<path>.*)$', "django.views.static.serve", {'document_root':
                                      os.path.join(settings.ROOT_PATH, 'site_media')})

You can move static files else where, just need to point 'document_root' to the correct path. Make sure comment out this url line for production deployment.

Solution 3

Actually, you can put your Javascript files (and all your static content) anywhere you want. I mean, Django does not impose a standard on where to place them, after all they won't be handled by Django, they'll be served by the webserver.

Said that, It's a good idea to keep them somewhere close to the project's files. I'd recommend to keep them in a sibling folder to your Django code. Same with MEDIA_ROOT.

It is a good idea to decouple your static files from python files because now you can put them in totally separate folders in a production environment and easily give different access to static files and python code (say FTP access, or permissions).

Something to keep in mind is that the settings' MEDIA_ROOT is the place where user's media files (that is uploaded content) will be placed, these are not your static project files, these are whatever files your Django app uploads (avatars, attachments, etc).

Proposed folder structure:

mysite.com/
  media/       - User media, this goes in settings.MEDIA_ROOT
  static/      - This is your static content folder
    css/
    js/
    images/
  templates/
  project/     - This is your Django project folder
    __init__.py
    manage.py
    settings.py
    myapp/
      __init__.py
      ...files..py

See the other responses recommendation on using Django's serve() function for development enviroment. Just make sure you add that url() to your urlpatterns under a settings.DEBUG is True conditional.

As for your templates, it's a good idea to use a context processor to send your static file's path to all your templates.

Share:
19,873
Nick Heiner
Author by

Nick Heiner

JS enthusiast by day, horse mask enthusiast by night. Talks I've Done

Updated on June 04, 2022

Comments

  • Nick Heiner
    Nick Heiner almost 2 years

    I know this has been asked before, but I'm having a hard time setting up JS on my Django web app, even though I'm reading the documentation.

    I'm running the Django dev server. My file structure looks like this:

    mysite/
          __init__.py
          MySiteDB
          manage.py
          settings.py
          urls.py
          myapp/
               __init__.py
               admin.py
               models.py
               test.py
               views.py
               templates/
                    index.html
    

    Where do I want to put the Javascript and CSS? I've tried it in a bunch of places, including myapp/, templates/ and mysite/, but none seem to work.

    From index.html:

    <head>
        <title>Degree Planner</title>
        <script type="text/javascript" src="/scripts/JQuery.js"></script>
        <script type="text/javascript" src="/media/scripts/sprintf.js"></script>
        <script type="text/javascript" src="/media/scripts/clientside.js"></script>
    </head>
    

    From urls.py:

    (r'^admin/', include(admin.site.urls)),
    (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': 'media'})
    (r'^.*', 'mysite.myapp.views.index'),
    

    I suspect that the serve() line is the cause of errors like:

    TypeError at /admin/auth/
    'tuple' object is not callable
    

    Just to round off the rampant flailing, I changed these settings in settings.py:

    MEDIA_ROOT = '/media/'
    MEDIA_URL = 'http://127.0.0.1:8000/media'
    

    UPDATE: I made some changes, but it's still not working:

    settings.py:

    ROOT_PATH = os.path.normpath(os.path.dirname(__file__))
    

    urls.py:

    (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': os.path.join(settings.ROOT_PATH, 'site_media')}),
    

    index.html:

    <script type="text/javascript" src="/media/JQuery.js"></script>
    <script type="text/javascript" src="/media/sprintf.js"></script>
    <script type="text/javascript" src="/media/clientside.js"></script>
    

    Filesystem:

    mysite/
          site_media/
                    JQuery.js
                    sprintf.js
                    clientside.js
          __init__.py
          settings.py
          manage.py
          -- etc
          myapp/
               -- app files, etc
    

    When I go to a url like http://127.0.0.1:8000/media/sprintf.js, I get:

    Page not found: /media/sprintf.js