What is the most common way to configure static files in debug and production for Django

前端 未结 2 1406
青春惊慌失措
青春惊慌失措 2021-02-02 04:39

When developing a Django application in debug mode, I serve static files using the following code:

if settings.DEBUG:
    urlpatterns += patterns(\'\',
        (         


        
2条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-02 05:06

    I'm putting this here in case someone wants an example of how to do this for Apache and WSGI. The question title is worded such that it's not just covering nginx.

    Apache/WSGI Daemon

    In my deployment, I decided to keep the database connection info out of the settings.py file. Instead I have a path /etc/django which contains the files with the database configuration. This is covered in some detail in an answer to another question. However, as a side effect, I can check for the presence of these files and the project being in a certain path to determine if this is running as a deployment, and in settings.py I define the settings IS_DEV, IS_BETA, and IS_PROD as True or False. Finding the project's directory from settings.py is just:

    # Find where we live.
    import os
    BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
    

    Anything that needs a path into the project uses BASE_DIR. So in urls.py, I have at the end:

    # Only serve static media if in development (runserver) mode.
    if settings.IS_DEV:
        urlpatterns += patterns('',
            url(r'^static/(?P.*)$', 'django.views.static.serve', 
                {'document_root': settings.MEDIA_ROOT, 
                'show_indexes': True}),
        )
    

    (I also have another URL in there that I use for UI testing and don't want on beta or production.)

    This covers the development server case. For production, I just have to set the Apache configuration up to serve the static stuff. (This is an intranet application with low to medium load, so I don't have a lightweight webserver like lighttpd to serve the static stuff, contrary to the Django docs' recommendation.) Since I'm using Fedora Core, I add a django.conf file in /etc/httpd/conf.d that reads similar to:

    WSGIDaemonProcess djangoproject threads=15
    WSGISocketPrefix /var/run/wsgi/wsgi
    
    Alias /django/static/ /var/www/djangoproject/static/
    Alias /django/admin/media/ /usr/lib/python2.6/site-packages/django/contrib/admin/media/
    WSGIScriptAlias /django /var/www/djangoproject/django.wsgi
    WSGIProcessGroup djangoproject
    
    
        Order deny,allow
        Allow from all
    
    
    
        Order deny,allow
        Allow from all
    
    

    IIRC, the key here is to put your Alias lines before your WSGIScriptAlias line. Also make sure that there's no way for the user to download your code; I did that by putting the static stuff in a static directory that is not in my Django project. That's why BASE_DIR gives the directory containing the Django project directory.

    You can omit the WSGISocketPrefix line. I have it because the admin wants the sockets in a non-default location.

    My WSGI file is at /var/www/djangoproject/django.wsgi (i.e. /django.wsgi in the Mercurial repository) and contains something like:

    import os
    import sys
    
    os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoproject.settings'
    os.environ['DB_CONFIG'] = '/etc/django/db_regular.py'
    thisDir = os.path.dirname(__file__)
    sys.path.append(thisDir)
    sys.path.append(os.path.join(thisDir, 'djangoproject'))
    sys.path.append(os.path.join(thisDir, 'lib'))
    
    import django.core.handlers.wsgi
    application = django.core.handlers.wsgi.WSGIHandler()
    

    The nice thing about WSGI daemons is that you just have to touch django.wsgi to restart your Django WSGI daemon; you don't need to reload or restart the Apache server. This makes the admin happy.

    Finally, since my /var/www/djangoproject is just a Mercurial repo, I have the following in /var/www/djangoproject/.hg/hgrc:

    [hooks]
    changegroup.1=find . -name \*.py[co] -exec rm -f {} \;
    changegroup.2=hg update
    changegroup.3=chgrp -Rf djangoproject . || true
    changegroup.4=chmod -Rf g+w,o-rwx . || true
    changegroup.5=find . -type d -exec chmod -f g+xs {} \;
    changegroup.6=touch django.wsgi # Reloads the app
    

    This clears Python bytecode, updates the working copy, fixes up all the perms, and restarts the daemon whenever a developer pushes into deployment, so anyone in the djangoproject group can push into it and not just the last one who added a file. Needless to say, be careful who you put in the djangoproject group.


    zeekay sets STATIC_URL, STATIC_ROOT, STATICFILES_DIRS, STATICFILES_FINDERS and uses "django.contrib.staticfiles" and "django.core.context_processors.static" in his settings. I don't have those since my code dates back to Django 1.1 and don't use {{ STATIC_ROOT }}.

    Hope this helps.

提交回复
热议问题