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.
Django's versatility allows it to be used for building a wide range of web applications. Here are some examples:
Understanding the distinction between a project and an app is crucial for organizing your Django codebase effectively.
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:
settings.py
,
urls.py
, and wsgi.py
.
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:
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.
django-admin startproject projectname
projectname/
manage.py
projectname/
__init__.py
settings.py
urls.py
wsgi.py
Within a Django project, you can create multiple apps to modularize your functionality. Each app is a Python package with a specific directory structure.
python manage.py startapp appname
appname/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
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.
python manage.py runserver
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.
The settings.py
file is the heart of your Django project
configuration. It contains various settings that control the behavior
of your application.
True
during development for detailed error messages and
False
in production.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / "db.sqlite3",
}
}
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'myuser',
'PASSWORD': 'mypassword',
'HOST': 'localhost',
'PORT': '5432',
}
}
The MVT pattern in Django separates concerns into three main components: Models, Views, and Templates.
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 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 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 define the routes for your application, mapping URLs to
views. This is configured using the urlpatterns
list.
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
path('authors/', views.author_list, name='author_list'),
]
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('appname.urls')),
]
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.
INSTALLED_APPS
in
settings.py
:
INSTALLED_APPS = [
...
'appname',
]
admin.py
:
from django.contrib import admin
from .models import Author
admin.site.register(Author)
python manage.py createsuperuser
http://127.0.0.1:8000/admin
to log in.
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
This command applies the migrations to your database, updating the schema to match your models.
python manage.py migrate
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 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!")
Class-based views are preferred for their scalability and organization, especially in larger applications where reusability and modularity are crucial.
Django supports multiple databases, each with its advantages and use cases.
In settings.py
, you can configure the database connection
settings for your Django project.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'myuser',
'PASSWORD': 'mypassword',
'HOST': 'localhost',
'PORT': '5432',
}
}
Django provides utilities to dynamically generate URLs, making your application more maintainable and robust.
from django.urls import reverse
from django.shortcuts import redirect
def my_view(request):
url = reverse('my_view_name')
return redirect(url)
<a href="{% url 'my_view_name' %}">Go to my view</a>
Templates are usually stored in the templates
directory
within each app or in a global templates directory.
appname/
templates/
appname/
my_template.html
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',
],
},
},
]
In Django templates, double curly braces {{ }}
are used
to render variables passed from views.
<p>Hello, {{ user.username }}!</p>
This will display the username of the logged-in user.
The {% %}
syntax is used for template tags, which provide
logic and control structures within templates.
<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 templates allows you to reuse common sections like headers or footers across multiple templates.
{% include 'header.html' %}
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 are files like CSS, JavaScript, and images that are not dynamically generated by the server but are necessary for your application.
To include static files in your Django project:
static
directory in your app folder.
settings.py
:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
BASE_DIR / "static",
]
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
<script src="{% static 'js/script.js' %}"></script>
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.
MEDIA_ROOT
is a setting in Django that defines the
directory where user-uploaded files are stored.
settings.py
:
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
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.
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.
settings.py
:
STATIC_ROOT = BASE_DIR / 'staticfiles'
python manage.py collectstatic
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.
A Foreign Key is a field that creates a many-to-one relationship between models. It is used to link one model to another.
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
.
books_by_author = Book.objects.filter(author__name='Author Name')
This query retrieves all books written by a specific author.
A One-to-One Field creates a one-to-one relationship between models. This is similar to a foreign key with a unique constraint.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField()
Each Profile
is associated with a single
User
.
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.
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
.
NULL
values in the database.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'.
author = Author.objects.create(name='John Doe')
This command creates a new Author
object and saves it to
the database.
authors = Author.objects.all()
This query retrieves all Author
objects from the
database.
author = Author.objects.get(id=1)
This query retrieves the Author
object with the specified
ID.
young_authors = Author.objects.filter(age__lt=30)
This query retrieves all authors who are younger than 30 years old.
author = Author.objects.get(id=1)
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.
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'.
A QuerySet is a collection of database queries. It allows you to read data from the database, filter it, and order it.
authors = Author.objects.filter(age__lt=30).order_by('name')
This QuerySet retrieves authors younger than 30 and orders them by name.
books = Book.objects.filter(author__name='John Doe')
This query retrieves all books written by the author named 'John Doe'.
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.
<form method="post">
{% csrf_token %}
<!-- form fields -->
</form>
This adds a hidden field with a CSRF token to the form.
Model forms allow you to create forms directly from your models, ensuring that the form fields match the model fields.
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) 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.
Signals allow you to execute some code when certain events occur. They provide a way to decouple different parts of your application.
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.
login_required
Decoratorfrom 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 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.
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.