Computer scienceBackendDjangoLaunching server

Static content

5 minutes read

Making your HTML pages visually appealing is essential. For that, you need to add some style to your pages using CSS or even do some programming with JavaScript. Both CSS and JavaScript run smoothly in your browser, so you only need to send these files to the user. Let's see how you can do it in a few steps with Django.

You rarely see sites serving static content (images, JavaScript, CSS) with Django because specialized tools work with it more effectively. However, you can serve content directly with Django for development or even for your pet project with only a few visitors.

Static files

HTML pages consist of three main parts:

  • HTML layout;
  • CSS;
  • JavaScript code.

Defining styles for pages in separate files is convenient to make our templates clear and easy to read. The same applies to JavaScript code. We know how to render templates, but how do we send other types of files to a client?

Let's refer to an example. We keep working on John Doe's blog, and this time, we want to add some style to it. Let's define a simple CSS file with just the properties for the h2 elements:

h2 {
  font-size: 24px;
  color: gray;
}

We save it to the file static/css/base.css relative to the project's root. Also, you need to define a template in the blog/templates/blog/index.html file:

{% load static %}
<link rel="stylesheet" href="{% static 'css/base.css' %}">

<h2>{{ blog_name }}</h2>
<div>{{ post.text }}</div>

We use the tag {% load static %} to tell Django that we want to import an additional tag for the templates named static. After that, we use the tag {% static 'css/base.css' %} as a URL to the stylesheet for the page.

Note that we only use the css/base.css part for the needed stylesheet; we omit the part of the URL that matches the STATIC_URL variable in the settings.py module.

However, if you try to launch the application using this template, nothing will happen to the style of the h2 element. We forgot to tell Django we want to use it to serve static files! Add this to the end of your settings.py module:

DEBUG = True

STATIC_URL = "/static/"
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]

Extend your urlpatterns in the urls.py module:

from django.conf import settings
from django.conf.urls.static import static

# your urlpatterns

urlpatterns += static(settings.STATIC_URL)

Now, you can relaunch the application, and serving static files will work like a charm! Your h2 element will have gray color; if you want to change it, you may refer to the table with other color names supported by major browsers.

DEBUG mode

The restriction for serving static files with Django is that it only works in the DEBUG mode. This is insecure and not suitable for production because when DEBUG is enabled, Django provides detailed error information, stack traces, and other debugging data that can be helpful for developers during debugging and testing. However, this also means that this information can be accessible to potential attackers who can launch attacks on your system or disclose sensitive data. Also, enabling debug mode can slow down your application and reduce its performance.

In a development environment, it is common to have DEBUG=True. This allows for easier testing and debugging as detailed error messages and stack traces are displayed. Developers can quickly identify and resolve issues during the development phase.

For QA (Quality Assurance) testing, the DEBUG setting can be either True or False, depending on the desired testing conditions. If you want to replicate a production-like environment and thoroughly test your application, it is recommended to set DEBUG=False. This ensures that your application behaves as it would in a production environment, where detailed error information is not exposed to users.

In a production environment, it is crucial to set DEBUG=False. This disables the detailed error messages and stack traces from being shown to users, enhancing security and protecting sensitive information. However, upon setting DEBUG=False, it's important to configure the ALLOWED_HOSTS setting correctly. The ALLOWED_HOSTS setting specifies the list of valid hostnames that can access your application, and it helps prevent unauthorized access to your production environment when your application is launched on a public server and is accessible from the Internet.

Since we cannot serve static files with Django in production, we need a way to tell the web server where to serve static files from. The files can be moved manually, but since it's such a typical operation, Django offers a mechanism called collectstatic to manage static files in a production environment efficiently. When developing a Django application, you typically store static files such as CSS, JavaScript, and images in a specific directory within the project. However, when deploying the application, it's recommended to use the collectstatic command.

The collectstatic command gathers all static files from various sources into a single directory, which can be configured in the project settings. This allows for centralized management and servicing of static files and utilizing different compression, minification, or caching tools to optimize their usage.

By separating the static file serving responsibility from Django and configuring your web server to serve these files directly, you enhance the security and performance of your application. Secure static file access is crucial to protect sensitive data and prevent unauthorized access.

Media files

Apart from HTML, a page may contain media files like images, videos, and audio files. To keep these files, we use the media folder on the server. It usually includes all users' media content we keep on the server. Adding this path to your project is no more complex than using static files.

First, we modify our settings.py module:

DEBUG = True

TEMPLATES[0]['OPTIONS']['context_processors'].append(
    'django.template.context_processors.media'
)

MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")

Then, extend urlpatterns:

from django.conf import settings
from django.conf.urls.static import static

# your urlpatterns

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Now, create the media folder in the project root and place a picture with the name media/avatar.jpg. Finally, save the new content in your template:

<h2>{{ blog_name }}</h2>

<div>Here am I</div>
<img src="{{ MEDIA_URL }}/avatar.jpg" alt="avatar">

<div>{{ post.text }}</div>

That's all! The blog has a nice profile picture of John Doe on the page.

Conclusion

Django provides tools to cover the development process of a site, including serving static and media files. However, it can only be used in debug mode, making it a starting point. To serve static files, configure settings and URL patterns, and add links to content in templates.

While using debug mode in production comes with some risks, in some specific cases, it's completely normal. Django provides the ability to work with static files in development and production.
4 learners liked this piece of theory. 0 didn't like it. What about you?
Report a typo