1. Folder Structure






Correct Folder Structure

myproject/
  static/
    css/
      base.css           ← global variables, reset, shared styles
      components/
        navbar.css
        card.css
        button.css
      pages/
        dashboard.css
        project-detail.css
    js/
      components/
        navbar.js
        modal.js
      pages/
        dashboard.js
        project-form.js
  templates/
    base.html
    components/
      navbar.html
      footer.html
      card.html
    projects/
      list.html
      detail.html
      form.html
    users/
      profile.html

2. Template Inheritance




base.html Required Blocks

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>{% block title %}App Name{% endblock %}</title>
  {% load static %}
  <link rel="stylesheet" href="{% static 'css/base.css' %}">
  {% block extra_css %}{% endblock %}
</head>
<body>
  {% include "components/navbar.html" %}

  <main>
    {% block content %}{% endblock %}
  </main>

  {% include "components/footer.html" %}

  <script src="{% static 'js/base.js' %}"></script>
  {% block extra_js %}{% endblock %}
</body>
</html>

Child Template Pattern

{% extends "base.html" %}
{% load static %}

{% block title %}Projects — App Name{% endblock %}

{% block extra_css %}
<link rel="stylesheet" href="{% static 'css/pages/projects.css' %}">
{% endblock %}

{% block content %}
<!-- page content here -->
{% endblock %}

{% block extra_js %}
<script src="{% static 'js/pages/projects.js' %}"></script>
{% endblock %}

3. CSS Standards








4. JavaScript Standards







5. Passing Data from Django to JavaScript

Use data-* attributes — never string interpolation in <script> tags.




Correct Pattern

<!-- template: projects/detail.html -->
{% block content %}
<div
  id="project-root"
  data-project-id="{{ project.id }}"
  data-workspace-id="{{ workspace.id }}"
  data-can-edit="{{ can_edit|yesno:'true,false' }}"
>
  <!-- content -->
</div>
{% endblock %}
// static/js/pages/project-detail.js
const root = document.getElementById('project-root');
const projectId = root.dataset.projectId;
const canEdit = root.dataset.canEdit === 'true';

CSRF Token in Fetch Requests

// static/js/base.js — included in base.html
function getCsrfToken() {
  return document.querySelector('[name=csrfmiddlewaretoken]')?.value
    ?? document.cookie.split('; ')
        .find(c => c.startsWith('csrftoken='))
        ?.split('=')[1] ?? '';
}

// Usage in any fetch call
fetch('/api/projects/', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-CSRFToken': getCsrfToken(),
  },
  body: JSON.stringify(data),
});

6. Reusable Template Components







Include with Context

<!-- Using a card component -->
{% for project in projects %}
  {% include "components/project-card.html" with project=project %}
{% endfor %}

7. Template Logic Rules





8. Static File Loading






9. Naming Standards







10. Anti-Patterns

Anti-Pattern Impact Fix
<style> block in template Styles can't be cached, inconsistent across pages Move to static/css/
<script> block with logic in template Can't be linted, can't be reused, hard to debug Move to static/js/
var x = "{{ variable }}" in script tag XSS risk, tightly coupled Use data-* attributes
onclick="doSomething()" inline Hard to maintain, can't be tested Use addEventListener in JS file
Page template not extending base.html Duplicate head/body markup, inconsistent layout Always extend base.html
Navbar HTML on every page One change needs updating every page {% include "components/navbar.html" %}
Complex Python-like logic in templates Moves business logic to templates Prepare data in view/service
Hardcoded /static/ paths Breaks when STATIC_URL changes Use {% static %} tag
app-name missing in template path Templates conflict across apps Use templates/app_name/file.html
Before Marking Done

11. Django Template Checklist — Before Marking Done

Folder Structure




Template Inheritance



CSS & JavaScript







Data, Components & Static









Naming & Mobile




Practice Task

Apply what you learned by building real Django templates with zero inline styles, zero inline scripts, and correct data-* attribute patterns. Covers: 3-folder structure, base.html inheritance, project list/form/detail templates, responsive grid in CSS with variables.

Open Task 02: Build the Project Detail Template