Free Ebook cover Django Fundamentals: From First App to a Complete Backend

Django Fundamentals: From First App to a Complete Backend

New course

12 pages

Django Fundamentals: Building and Running Your First Backend Project

Capítulo 1

Estimated reading time: 7 minutes

+ Exercise

1) Create a clean Python environment

A clean environment isolates your project’s dependencies (Django version, libraries) from other projects on your machine. This prevents “works on my machine” issues and makes your backend reproducible.

Step-by-step: create and activate a virtual environment

  • Create a project folder (example: first_backend/) and enter it.
  • Create a virtual environment named .venv (a common convention).
  • Activate it.
  • Install Django.
# macOS/Linux (bash/zsh) example commands
mkdir first_backend
cd first_backend
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install django

# Windows (PowerShell) example commands
mkdir first_backend
cd first_backend
py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install django

Verify Django is available inside the environment:

python -m django --version

2) Create a new Django project

A Django “project” is the container for settings and configuration. Inside it, you’ll create one or more “apps” that hold features (e.g., accounts, blog, payments).

Step-by-step: start a project

Run django-admin to generate the project scaffold. The trailing dot (.) tells Django to create files in the current directory (keeps the folder structure tidy).

django-admin startproject config .

You should now see a structure similar to:

Continue in our app.

You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.

Or continue reading below...
Download App

Download the app

first_backend/
  manage.py
  config/
    __init__.py
    settings.py
    urls.py
    asgi.py
    wsgi.py

3) Understand manage.py and core project files

manage.py: your project command runner

manage.py is a small script that sets the correct Django settings module and then delegates to Django’s command-line system. You use it for tasks like running the dev server, creating apps, running migrations, opening a Django shell, and more.

Examples of commands you’ll commonly run:

  • python manage.py runserver (start development server)
  • python manage.py startapp core (create an app)
  • python manage.py check (validate configuration)

config/settings.py: configuration for this project

This file defines settings such as installed apps, middleware, templates, database configuration, static files, and security-related options. In development you’ll tweak settings frequently; in production you’ll typically split settings or use environment variables.

config/urls.py: the URL entry point

This file is the top-level URL router. It maps URL paths to views (or includes other URL modules). As your project grows, you’ll usually keep this file small and delegate routing to each app.

config/wsgi.py and config/asgi.py: deployment entry points

  • wsgi.py is used by WSGI servers (traditional synchronous deployments).
  • asgi.py is used by ASGI servers (async-capable deployments, websockets, etc.).

You typically don’t edit these often early on, but it’s important to know they exist for deployment.

4) Run the development server

Step-by-step: start the server

python manage.py runserver

By default, Django serves on http://127.0.0.1:8000/. Visit that URL in your browser. If everything is set up correctly, you’ll see Django’s default success page.

What the dev server is (and isn’t)

  • It’s a convenience server for local development: auto-reload, helpful error pages, quick iteration.
  • It is not intended for production traffic or hardened security.

5) Trace the request/response cycle (high level)

When you request a URL in Django, the flow looks like this:

  1. Browser/client sends an HTTP request to the server (e.g., GET /hello/).
  2. Django receives the request through the server interface (dev server now; WSGI/ASGI in deployment).
  3. Middleware runs (a chain of components that can modify the request/response, handle sessions, authentication, security headers, etc.).
  4. URL routing matches a path in config/urls.py (and included app URL modules).
  5. A view runs (a Python function or class) and returns an HttpResponse (HTML, JSON, redirect, 404, etc.).
  6. Django builds the final response (middleware can modify it on the way out).
  7. Server sends the HTTP response back to the client.

For a backend API, the “view returns JSON” is a common pattern; for a server-rendered site, the view often renders a template into HTML.

6) Create your first app and wire it in

An “app” is a self-contained feature unit: it can have its own URLs, views, models, templates, tests, and admin configuration. Even for small projects, using apps helps keep code organized.

Step-by-step: create an app

python manage.py startapp core

This creates:

core/
  __init__.py
  admin.py
  apps.py
  migrations/
    __init__.py
  models.py
  tests.py
  views.py

Register the app in INSTALLED_APPS

Open config/settings.py and add the app config to INSTALLED_APPS:

# config/settings.py
INSTALLED_APPS = [
    # ... default Django apps ...
    'core.apps.CoreConfig',
]

This tells Django to include the app in project discovery (models, migrations, admin, etc.).

7) Add a simple URL route and view

To confirm everything is wired correctly, you’ll create a minimal view and map it to a URL.

Create a view

Edit core/views.py:

# core/views.py
from django.http import HttpResponse


def hello(request):
    return HttpResponse("Hello from Django!")

Create app-level URLs

Create a new file core/urls.py:

# core/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('hello/', views.hello, name='hello'),
]

Include the app URLs in the project URLs

Edit config/urls.py:

# config/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('core.urls')),
]

Now run the server (or let it auto-reload) and visit:

http://127.0.0.1:8000/hello/

You should see: Hello from Django!

8) Use Django’s debugging error pages effectively

In development, Django’s debug pages are designed to help you locate errors quickly. They show stack traces, local variables, and the exact line that failed.

Trigger a controlled error to see the debug page

Temporarily change the view to raise an exception:

# core/views.py
from django.http import HttpResponse


def hello(request):
    1 / 0
    return HttpResponse("Hello from Django!")

Reload /hello/. You’ll see a detailed error page with:

  • Exception type (e.g., ZeroDivisionError)
  • Traceback showing the call stack
  • Source code context around the failing line
  • Request information (path, method, headers)

Undo the error after confirming the debug page works.

Understand when debug pages appear

  • They appear when DEBUG = True in config/settings.py.
  • When DEBUG = False, Django shows generic error pages (and you must configure allowed hosts, logging, and proper error handling).

Common “first setup” errors and what they mean

SymptomLikely causeWhere to look
404 Not Found on /hello/URL not included or path mismatchconfig/urls.py, core/urls.py
ModuleNotFoundError for coreApp not created, wrong name, or not on pathFolder name, INSTALLED_APPS
Server won’t start, settings errorSyntax error or misconfigurationconfig/settings.py, terminal output

9) Conventions for organizing code as the project grows

Early structure decisions make a big difference later. The goal is to keep responsibilities clear: project configuration in the project package, feature code in apps.

Keep project URLs thin; route by app

As you add apps, include each app’s URL module:

# config/urls.py
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('core.urls')),
    path('accounts/', include('accounts.urls')),
    path('api/', include('api.urls')),
]

Use consistent app naming

  • Prefer short, descriptive app names: core, accounts, billing, inventory.
  • Avoid generic names like utils for large mixed responsibilities; if you need shared helpers, keep them small and well-scoped.

Introduce a predictable layout inside each app

Django creates a minimal layout, but you can expand it as complexity increases. A common pattern is to split large files into modules:

core/
  views/
    __init__.py
    health.py
    pages.py
  urls.py
  services/
    __init__.py
    greeting.py
  templates/
    core/
      home.html

This keeps views.py from becoming a “mega-file” and encourages separation between HTTP handling (views) and business logic (services).

Adopt a “thin views” mindset

As you move beyond a hello-world response, keep views focused on HTTP concerns (parsing input, returning responses) and move business rules into dedicated functions/classes. This improves testability and readability.

Use explicit imports and clear boundaries

  • Views import from services or models rather than duplicating logic.
  • Apps should avoid circular dependencies; if two apps need shared logic, consider a small, dedicated app (e.g., common) with a narrow purpose.

Now answer the exercise about the content:

In a Django project, what is the main purpose of register an app like core in INSTALLED_APPS?

You are right! Congratulations, now go to the next page

You missed! Try again.

Adding an app to INSTALLED_APPS tells Django to include it in project discovery, so features like models, migrations, and admin integration are recognized and loaded.

Next chapter

Django Project Structure, Apps, and URL Routing for Backend Features

Arrow Right Icon
Download the app to earn free Certification and listen to the courses in the background, even with the screen off.