Django Essentials: Step-by-Step Learning
→ Django Tutorial in HTML Version
What is Django?
Django is a powerful and flexible Python-based web framework designed to streamline the development process of web applications. It focuses on making web development faster and more straightforward by offering reusable components, encouraging rapid development, and adhering to the “Don’t Repeat Yourself” (DRY) principle. Django comes with numerous built-in features, including an ORM (Object-Relational Mapping) for database interactions, a comprehensive authentication system, and a user-friendly admin interface for managing application data.
Key Features of Django
- Rapid Development: Django includes many built-in functionalities that reduce the time and effort needed to build complex web applications.
- Scalability: Designed to accommodate the needs of both small and large-scale projects.
- Security: Django helps developers avoid many common security mistakes, including SQL injection, cross-site scripting, and cross-site request forgery.
- Versatility: Suitable for a variety of projects, from simple websites to complex web applications.
What Can You Build with Django?
Django’s versatility allows it to be used for building a wide range of web applications. Here are some examples:
Types of Applications
- Content Management Systems (CMS): Manage and organize web content easily.
- E-commerce Websites: Handle product listings, shopping carts, and payment gateways.
- Social Media Platforms: Create user profiles, messaging systems, and activity feeds.
- Scientific Computing Platforms: Manage and analyze large datasets and complex computations.
- APIs: Using Django REST Framework to create robust and scalable APIs.
- Web Applications with Complex Data Requirements: Handle intricate business logic and large volumes of data efficiently.
Difference Between a Project and an App in Django
Understanding the distinction between a project and an app is crucial for organizing your Django codebase effectively.
Project
A Django project is a collection of settings and configurations for your web application. It defines the overall structure and behavior of your site. A project typically includes:
- Global Settings: Configurations that apply to the entire project, such as database settings and middleware.
- URL Routing: A central place to define the URL patterns for the project.
- Project-Specific Files: Such as
settings.py
,urls.py
, andwsgi.py
.
App
An app is a self-contained module within a Django project that handles specific functionalities. Each app is responsible for a distinct part of your application. For example, an e-commerce project might have separate apps for managing products, orders, and users. An app includes:
- Models: Define the data structure and interact with the database.
- Views: Handle the logic for displaying data and processing user input.
- Templates: Define the HTML structure for rendering data.
- Static Files: Contain assets like CSS, JavaScript, and images.
How to Start a Django Project
To create a new Django project, you can use the django-admin
command-line utility. This utility sets up the initial project structure, including essential configuration files.
Command to Create a Project
django-admin startproject projectname
Generated Project Structure
projectname/
manage.py
projectname/
__init__.py
settings.py
urls.py
wsgi.py
- manage.py: A command-line utility to manage your project, including running the development server and performing database migrations.
- projectname/settings.py: The configuration file for your project, containing settings for databases, installed apps, middleware, and more.
- projectname/urls.py: The URL configuration file, mapping URL patterns to views.
- projectname/wsgi.py: An entry-point for WSGI-compatible web servers to serve your project.
How to Start a Django App
Within a Django project, you can create multiple apps to modularize your functionality. Each app is a Python package with a specific directory structure.
Command to Create an App
python manage.py startapp appname
Generated App Structure
appname/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
- models.py: Defines the data models (database schema) for the app.
- views.py: Contains the logic for handling requests and returning responses.
- admin.py: Configures the admin interface for managing app data.
- migrations/: Directory to store database migration files.
How to Run the Development Server
Django comes with a lightweight development server that allows you to test your application locally. This server is not suitable for production but is perfect for development and testing.
Command to Start the Server
python manage.py runserver
Accessing the Development Server
Once the server is running, you can access your application at http://127.0.0.1:8000/
. This URL points to your local machine's IP address and port 8000.
Understanding the settings.py File
The settings.py
file is the heart of your Django project configuration. It contains various settings that control the behavior of your application.
Key Configurations in settings.py
- DEBUG: A boolean that should be set to
True
during development for detailed error messages andFalse
in production. - ALLOWED_HOSTS: A list of strings representing the host/domain names that the Django site can serve.
- DATABASES: Configuration for connecting to your database. Example:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / "db.sqlite3",
}
}
- INSTALLED_APPS: A list of applications that are enabled in your project. Each app is represented by a string of its full Python path.
- MIDDLEWARE: A list of middleware components that process requests and responses.
- TEMPLATES: Configuration for the template engine, including the directories to search for templates and context processors.
Example Configuration Snippet
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'myuser',
'PASSWORD': 'mypassword',
'HOST': 'localhost',
'PORT': '5432',
}
}
Models, Views, and Templates (MVT) in Django
The MVT pattern in Django separates concerns into three main components: Models, Views, and Templates.
Models
Models define the structure of your database. Each model class represents a table in the database, and each attribute of the class represents a field in the table.
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
Views
Views handle the logic of your application. They process user requests, interact with models to fetch data, and return responses.
from django.shortcuts import render
from .models import Author
def author_list(request):
authors = Author.objects.all()
return render(request, 'author_list.html', {'authors': authors})
Templates
Templates define the presentation layer of your application. They are HTML files that display data provided by the views.
<!DOCTYPE html>
<html>
<head>
<title>Author List</title>
</head>
<body>
<h1>Author List</h1>
<ul>
{% for author in authors %}
<li>{{ author.name }} ({{ author.age }} years old)</li>
{% endfor %}
</ul>
</body>
</html>
URL Patterns and Configuration
URL patterns define the routes for your application, mapping URLs to views. This is configured using the urlpatterns
list.
Example Configuration
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
path('authors/', views.author_list, name='author_list'),
]
Including App URLs in Project URL Configuration
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('appname.urls')),
]
Django Admin Panel
The Django admin interface is a powerful tool that allows you to manage your application data easily. It provides a web-based interface to create, update, delete, and view the data models.
Enabling the Admin Interface
- Add your app to
INSTALLED_APPS
insettings.py
:
INSTALLED_APPS = [ ... 'appname', ]
2. Register models in admin.py
:
from django.contrib import admin
from .models import Author
admin.site.register(Author)
3. Create a superuser to access the admin interface:
python manage.py createsuperuser
4. Run the development server and visit http://127.0.0.1:8000/admin
to log in.
makemigrations and migrate in Django
makemigrations
This command generates migration files based on the changes you make to your models. Migrations are a way of propagating changes you make to your models into the database schema.
python manage.py makemigrations
migrate
This command applies the migrations to your database, updating the schema to match your models.
python manage.py migrate
Class-Based vs. Function-Based Views
Function-Based Views (FBV)
Function-based views are simple and easy to use, especially for straightforward logic.
from django.http import HttpResponse
def home(request):
return HttpResponse("Welcome to the home page!")
Class-Based Views (CBV)
Class-based views provide a more organized and reusable structure, making them ideal for more complex applications.
from django.views import View
from django.http import HttpResponse
class HomeView(View):
def get(self, request):
return HttpResponse("Welcome to the home page!")
Preference
Class-based views are preferred for their scalability and organization, especially in larger applications where reusability and modularity are crucial.
Preferred Databases with Django
Django supports multiple databases, each with its advantages and use cases.
Commonly Used Databases
- SQLite: Suitable for development and testing due to its simplicity and zero configuration.
- PostgreSQL: Preferred for production environments because of its robustness, advanced features, and reliability.
- MySQL: Another popular choice for production, known for its speed and wide usage.
Configuring Database Connection in Django
In settings.py
, you can configure the database connection settings for your Django project.
Example Configuration for PostgreSQL
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'myuser',
'PASSWORD': 'mypassword',
'HOST': 'localhost',
'PORT': '5432',
}
}
Dynamic URL Access in Django
Django provides utilities to dynamically generate URLs, making your application more maintainable and robust.
Using reverse in Views
from django.urls import reverse
from django.shortcuts import redirect
def my_view(request):
url = reverse('my_view_name')
return redirect(url)
Using {% url %} in Templates
<a href="{% url 'my_view_name' %}">Go to my view</a>
Storing Templates in Django
Templates are usually stored in the templates
directory within each app or in a global templates directory.
Example Structure
appname/
templates/
appname/
my_template.html
Configuring settings.py to Include Template Directories
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Understanding Double Curly Braces {{ }} in Templates
In Django templates, double curly braces {{ }}
are used to render variables passed from views.
Example
<p>Hello, {{ user.username }}!</p>
This will display the username of the logged-in user.
Using {% %} in Django Templates
The {% %}
syntax is used for template tags, which provide logic and control structures within templates.
Example of a Loop
<ul>
{% for author in authors %}
<li>{{ author.name }}</li>
{% endfor %}
</ul>
This loop will iterate over the authors
queryset and render each author's name in an unordered list.
Including and Extending Templates
Including Templates
Including templates allows you to reuse common sections like headers or footers across multiple templates.
{% include 'header.html' %}
Extending Templates
Template inheritance allows you to create a base template and extend it in other templates, promoting DRY principles.
{% extends 'base.html' %}
{% block content %}
<h1>Welcome</h1>
{% endblock %}
This extends base.html
and defines content for the content
block.
Static Files in Django
What are Static Files?
Static files are files like CSS, JavaScript, and images that are not dynamically generated by the server but are necessary for your application.
Including Static Files
To include static files in your Django project:
- Create a
static
directory in your app folder. - Configure
settings.py
:
STATIC_URL = '/static/' STATICFILES_DIRS = [ BASE_DIR / "static", ]
3. Load static files in templates:
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
<script src="{% static 'js/script.js' %}"></script>
Configuring Static Files in Development
During development, Django can serve static files for you. Ensure django.contrib.staticfiles
is included in INSTALLED_APPS
, then use python manage.py runserver
to serve static files automatically.
What is Media Root?
MEDIA_ROOT
is a setting in Django that defines the directory where user-uploaded files are stored.
Configuring Media Root
- Add the media root and URL settings to
settings.py
:
MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR / 'media'
2. Serve media files during development:
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
This configuration ensures that media files are accessible during development.
What is collectstatic in Django?
collectstatic
is a Django management command that collects all static files from your apps and places them in a single directory specified by the STATIC_ROOT
setting.
Using collectstatic
- Configure
settings.py
:
STATIC_ROOT = BASE_DIR / 'staticfiles'
2. Run the command:
python manage.py collectstatic
python manage.py collectstatic
Serving Static Files in Production
In production, you’ll need a web server like Nginx to serve static files. Configure your web server to serve files from the STATIC_ROOT
directory.
Foreign Keys in Django
A Foreign Key is a field that creates a many-to-one relationship between models. It is used to link one model to another.
Defining a Foreign Key
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
In this example, each Book
is linked to an Author
.
Querying with Foreign Keys
books_by_author = Book.objects.filter(author__name='Author Name')
This query retrieves all books written by a specific author.
One-to-One Field in Django
A One-to-One Field creates a one-to-one relationship between models. This is similar to a foreign key with a unique constraint.
Defining a One-to-One Field
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField()
Each Profile
is associated with a single User
.
Many-to-Many Field in Django
A Many-to-Many Field creates a many-to-many relationship between models, allowing each instance of one model to be associated with multiple instances of another model.
Defining a Many-to-Many Field
class Student(models.Model):
name = models.CharField(max_length=100)
class Course(models.Model):
title = models.CharField(max_length=200)
students = models.ManyToManyField(Student)
Each Course
can have multiple Students
, and each Student
can enroll in multiple Courses
.
Character Field Attributes in Django
Common Attributes for Character Fields
- max_length: Defines the maximum length of the field.
- default: Sets a default value for the field.
- null: Allows
NULL
values in the database. - blank: Allows the field to be blank in forms.
Example
class Author(models.Model):
name = models.CharField(max_length=100, default='Anonymous')
This example creates a name
field with a maximum length of 100 characters and a default value of 'Anonymous'.
Basic Database Queries in Django
Creating Objects
author = Author.objects.create(name='John Doe')
This command creates a new Author
object and saves it to the database.
Retrieving All Objects
authors = Author.objects.all()
This query retrieves all Author
objects from the database.
Retrieving a Single Object
author = Author.objects.get(id=1)
This query retrieves the Author
object with the specified ID.
Filtering Objects
young_authors = Author.objects.filter(age__lt=30)
This query retrieves all authors who are younger than 30 years old.
Querying a Single Element from a Database Table
Example
author = Author.objects.get(id=1)
Handling DoesNotExist Exception
from django.core.exceptions import ObjectDoesNotExist
try:
author = Author.objects.get(id=1)
except ObjectDoesNotExist:
print("Author not found")
This ensures your application handles cases where the queried object does not exist.
Filtering Items by Multiple Attributes
Example
authors = Author.objects.filter(age__lt=30, name__icontains='john')
This query retrieves authors who are younger than 30 years old and whose name contains ‘john’.
Model Sets and Their Usage
A QuerySet is a collection of database queries. It allows you to read data from the database, filter it, and order it.
Example
authors = Author.objects.filter(age__lt=30).order_by('name')
This QuerySet retrieves authors younger than 30 and orders them by name.
Querying Upwards in a Model Relationship
Example
books = Book.objects.filter(author__name='John Doe')
This query retrieves all books written by the author named ‘John Doe’.
CSRF Tokens and Their Usage
CSRF (Cross-Site Request Forgery) tokens are used to protect forms from CSRF attacks, ensuring that the form submission is coming from the authenticated user.
Using CSRF Tokens
<form method="post">
{% csrf_token %}
<!-- form fields -->
</form>
This adds a hidden field with a CSRF token to the form.
Model Forms in Django
Model forms allow you to create forms directly from your models, ensuring that the form fields match the model fields.
Creating a Model Form
from django import forms
from .models import Author
class AuthorForm(forms.ModelForm):
class Meta:
model = Author
fields = ['name', 'age']
This form can be used to create or update Author
instances.
Django REST Framework (DRF) and Its Importance
Django REST Framework (DRF) is a powerful and flexible toolkit for building Web APIs in Django. It simplifies the process of building RESTful APIs, offering a wide range of features out of the box.
Why Use DRF?
- Flexibility: Provides a customizable and modular approach to building APIs.
- Serialization: Converts complex data types, such as querysets and model instances, into native Python data types.
- Authentication: Supports various authentication methods, including token-based authentication and OAuth.
- Pagination: Easily add pagination to API responses.
- Browsable API: Automatically generates a web-based interface for your API.
Signals in Django
Signals allow you to execute some code when certain events occur. They provide a way to decouple different parts of your application.
Example: Post-Save Signal
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Author
@receiver(post_save, sender=Author)
def author_saved(sender, instance, **kwargs):
print(f'Author {instance.name} saved.')
This signal is triggered every time an Author
instance is saved, printing a message to the console.
Preventing Unauthorized Users from Viewing Certain Pages
Using the login_required
Decorator
from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
return HttpResponse("Hello, authenticated user!")
This decorator restricts access to the view, ensuring that only authenticated users can access it.
Serializers in Django REST Framework
Serializers convert complex data types, such as querysets and model instances, into native Python data types that can be rendered into JSON, XML, or other content types.
Example
from rest_framework import serializers
from .models import Author
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ['id', 'name', 'age']
This serializer converts Author
instances to a JSON representation and vice versa.