开始构建 Web 应用程序不仅需要对编码和设计原则有深入的了解,还需要对安全性和性能坚定不移的承诺。在数字化存在至关重要的时代,构建强大而高效的在线平台的能力是一项具有不可估量价值的技能。本教程专门面向网络工匠,即那些希望将技术线索编织成功能性和安全性的织锦的人。
我们的努力将是使用 Django 创建一个 Web 应用程序,Django 是一个高级 Python Web 框架,鼓励快速开发和简洁、务实的设计。Django 以其简单性和多功能性而闻名,它构成了我们项目的支柱,确保我们的重点可以放在我们创作的独特性上,而不是其框架的复杂性上。
我们将以有条不紊的方式开展这项事业,分为十个基本步骤。每一步都是一个里程碑,标志着我们从头开始构建应用程序时所取得的进展。
我们通过配置开发环境、将工作区封装在虚拟信封内来奠定项目的基石,在虚拟信封中,应用程序的依赖项可以和谐地驻留在其中,而不受外部冲突的影响。
就像在一场盛大的表演之前搭建舞台一样,我们从一开始就配置我们的应用程序以遵守安全性限制和高性能要求。
我们应用程序数据的完整性至关重要。我们将集成以其可靠性和稳健性而闻名的 PostgreSQL,确保我们的数据位于堡垒内,不受外部威胁的影响。
在这里,我们定义了应用程序的本质 - Book 模型 - 通过精心构造的数据字段捕获每卷所包含的知识财富。
信任是网络的货币。我们将建立一个身份验证系统,不仅验证身份,而且坚定不移地勤勉维护用户信息的机密性。
赋予管理员权力后,他们就有责任精确且保护地管理数据。我们的管理界面将证明这种平衡。
视图和模板是用户感知我们的应用程序的镜头。我们将着眼于美观和安全的数据表示来制作它们。
我们的应用程序的中间件将充当无声的守护者,执行安全策略和缓存策略,以确保无缝、快速的用户体验。
当我们准备应用程序向世界展示其外观时,我们确保每张图像、每个样式表都能高效交付,并可能利用内容交付网络的力量。
当我们的努力接近顶峰时,我们将彻底测试我们的应用程序,将其部署到强大的虚拟专用服务器,并设置持续监控。这确保了它在开始与现实世界交互时保持响应能力和弹性。
请记住,制作我们的网络应用程序的冒险与精美的产品本身一样有意义。每一步都是对提高您的技能和加深您的理解的友好推动。通过克服每个挑战获得的知识是任何开发人员旅程的真正奖励。让我们开始吧。
将您的开发环境想象成您的个人工作室。就像木匠不希望一个项目的锯末干扰另一个项目一样,我们使用 Python 中的虚拟环境将项目的库和依赖项保留在自己整洁的小空间中。
让我们深入研究虚拟环境并让我们的工作空间变得舒适。这只是您终端中快速的命令舞蹈。对于 Linux 或 macOS,它有点像这样:
python3 -m venv myenv
source myenv/bin/activate
对于 Windows,您将输入:
python -m venv myenv
myenv\Scripts\activate
myenv
当您在命令提示符之前的括号中看到环境名称 ( ) 时,您就会知道它已生效。
激活我们的环境后,是时候将 Django 引入其中了。Django 只需一个pip
命令即可:
pip install django
至此,Django 就听我们指挥了,准备帮助我们构建一些令人惊奇的东西。
现在,让我们召唤Django自己的魔力来创建我们项目的骨架,这就像建立建筑物的地基和框架一样:
django-admin startproject my_awesome_bookstore
导航到您的新项目文件夹:
cd my_awesome_bookstore
现在我们已经有了它——我们的网络应用程序的坚实基础,准备好立即付诸行动。在这第一步中,我们精心打造了一个一尘不染的工作区,并配有自己的虚拟环境。
我们已邀请 Django 加入我们的工具包,并展开了我们的 Web 应用程序的架构计划。这有点像建立一个新的工作室,所有的东西都被组织起来,贴上标签,并为第一天的制作做好准备。您已经在创造力和学习的马拉松中迈出了第一步,这个过程一定会像您打开数字书店大门的那一天一样有意义。
将您的 Django 项目想象成一个繁华的城镇,将您的应用程序想象成填充其中的商店和服务。是时候建立我们的第一个机构了。在您的终端中,激活虚拟环境并在项目目录中,您将运行:
python manage.py startapp bookshelf
该命令制作了一个新的“书架”应用程序 - 我们在数字小镇中的舒适角落,用户将在这里浏览我们展示的书籍。
现在,让我们为我们的应用程序提供相当于坚固的门和可靠的警报系统的功能。打开settings.py
项目目录中的文件。该文件就像我们应用程序的控制面板,我们将在此处调整一些控制杆和旋钮以增强安全性和性能(关于其中一些我们将在稍后讨论)。
# settings.py
# Import the os module for path settings
import os
# ... (other settings above)
# It's crucial to turn off debug mode when you go live. This prevents the display of sensitive information in error messages.
DEBUG = False
# This is where you list the host/domain names that your Django site can serve. It's a security measure to prevent HTTP Host header attacks.
ALLOWED_HOSTS = ['daniel.com', 'www.daniel.com']
# Database
DATABASES = {
'default': {
# We specify the backend
'ENGINE': 'django.db.backends.postgresql',
# Database name
'NAME': 'mydatabase',
# Database user should be unique to this application for security purposes.
'USER': 'myuser',
# The password for your database user. Keep this secret!
'PASSWORD': 'mypassword',
# Host where your database server is running - typically localhost for a single server setup.
'HOST': 'localhost',
# The port number your database listens on. It's usually set to the default port of the database.
'PORT': '',
}
}
# Setting up caching. Even a simple local memory cache can help improve performance by storing frequently accessed data in memory.
CACHES = {
'default': {
# Using the local memory cache backend, which is quick and suitable for single-process environments.
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
# A unique name for this cache instance. It's like labeling a box in a warehouse so you can find it easily later.
'LOCATION': 'unique-snowflake',
}
}
# Configure static files settings, integrating WhiteNoise for serving static files in production
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') # Define the directory for collected static files
STATICFILES_DIRS = ( # Additional locations for static files
os.path.join(BASE_DIR, 'static'),
)
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' # WhiteNoise storage for static files
# Media files configuration
MEDIA_URL = '/media/'
# We'll ensure our app's chats are VIP-only by always using HTTPS, turning every conversation into a private, encrypted whisper.
SECURE_SSL_REDIRECT = True # Redirects all non-HTTPS requests to HTTPS
SESSION_COOKIE_SECURE = True # Ensures cookies are only sent over HTTPS
CSRF_COOKIE_SECURE = True # Ensures CSRF cookies are only sent over HTTPS
# Protects against clickjacking by preventing your Django site from being rendered inside a frame or iframe.
X_FRAME_OPTIONS = 'DENY'
# Add WhiteNoise to middleware for serving static files efficiently
MIDDLEWARE = [
# ... (other middleware entries)
'whitenoise.middleware.WhiteNoiseMiddleware',
# ... (other middleware entries)
]
# ... (remaining settings)
让我们让 Django 应用程序准备好成为众人瞩目的焦点,使用 WhiteNoise 来管理我们的静态文件,并将其与 PostgreSQL 数据库结合在一起以获得强大的性能。就像大师准备交响乐一样,我们将调整settings.py
并撒入一些额外的包,以确保一切都很好地配合在一起。
因此,拿起你的 pip 魔杖,让我们安装那些将为我们的应用程序带来额外魅力的软件包。以下是我们将要做什么以及为什么它会让我们的应用程序大放异彩的小指南。确保您已激活虚拟环境:
# For Unix-like systems (Linux/macOS)
pip install django psycopg2-binary Whitenoise
# For Windows systems
pip install django psycopg2 Whitenoise
该psycopg2-binary
软件包是一个独立的软件包,适用于类 Unix 系统,其中包括 psycopg2 PostgreSQL 适配器,并且不需要任何外部依赖项。在 Windows 上,我们安装的psycopg2
是 PostgreSQL 适配器本身。
通过设置DEBUG
和False
配置ALLOWED_HOSTS
,我们可以确保不会泄露任何意外信息,并且我们的应用程序确切地知道它所在的位置。集成 PostgreSQL 为我们提供了一个强大的数据库,并且设置简单的缓存策略可以使页面加载快速。
这仅仅是个开始。随着我们的应用程序旅程的展开和我们的数字社区的蓬勃发展,我们将打开引擎盖并调整我们的设置,根据我们用户社区不断增长的脉搏进行定制。
通过这些初步的调整,我们的应用程序已准备好进入数字世界。对于应用程序来说这只是一小步,但对于我们的项目来说却是巨大的飞跃!这有点像打开一家新商店的大门——油漆是新鲜的,货架是坚固的,我们已经准备好欢迎访客。我们的书架应用程序将成为 Django 项目繁华小镇中深受喜爱的一站。
现在,是时候为我们应用程序的宝贵数据建立一个安全的角落了。我们将把它们全部放入 PostgreSQL,这是一个像老橡树一样坚固可靠的数据库。它是我们信息的完美数字堡垒。但我们不会就此止步——我们还将通过使用环境变量来存储数据库凭据来实现关键的安全实践。
让我们完善应用程序的数据库设置。将 PostgreSQL 想象为值得信赖的库,我们应用程序的所有故事都在这里发生——安全、健全且组织良好。用户数据的每一章都在书架上得到了一个舒适的位置,这都要归功于 PostgreSQL 在安全性和性能方面的良好声誉。
想象一下,如果有人把图书馆的钥匙留在了迎宾垫下。不太明智,对吧?这正是我们不只是在代码中乱写数据库访问秘密的原因。相反,我们会将它们隐藏在环境变量中,就像魔术师斗篷中的秘密口袋一样,远离窥探的眼睛。
以下是如何转换settings.py
从这些环境变量中调出数据库设置的方法:
# settings.py
import os
from dotenv import load_dotenv
# Initialize the dotenv library to load the .env file
load_dotenv()
# ... (other settings)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DB_NAME', 'mydatabase'), # Default if not found
'USER': os.environ.get('DB_USER', 'myuser'), # Default if not found
'PASSWORD': os.environ.get('DB_PASSWORD'), # No default, must be set
'HOST': os.environ.get('DB_HOST', 'localhost'), # Default if not found
'PORT': os.environ.get('DB_PORT', ''), # Default if not found
}
}
# ... (other settings)
您将把数据库凭据存储在.env
项目根目录下的文件中,该文件不应提交给您的版本控制系统(例如 Git):
# .env file
DB_NAME=mydatabase
DB_USER=myuser
DB_PASSWORD=securepassword123
DB_HOST=localhost
DB_PORT=5432
通过使用环境变量,我们创建了灵活且安全的配置,将敏感信息排除在代码库之外。这就像只有您的应用程序和数据库知道的秘密握手。
现在,PostgreSQL 成为我们数据层的支柱,环境变量充当我们秘密的守护者,我们已经强化了应用程序的基础设施。它已准备好容纳我们的“书架”中将容纳的大量信息,防止窥探并为性能做好准备。
现在让我们过渡到制作数字书架的本质——书籍模型。该模型是我们如何在数据库中存储与书籍相关的数据的蓝图,就像图书馆员如何对书籍进行分类以使它们易于发现一样。
在 Django 的世界中,模型是有关数据的唯一真实来源。它们包含您所存储的数据的基本字段和行为。Django遵循DRY原则(Don't Repeat Yourself),因此每条信息都定义一次且仅一次。
Book
以下是我们的模型在models.py
书架应用程序文件中的示例:
# Import the models module from Django to define our database schema as Python classes
from django.db import models
# Define a new class called Book, which is a Django Model, meaning it will be represented as a table in the database
class Book(models.Model):
# Define a character field for the book title with a maximum length of 200 characters
title = models.CharField(max_length=200)
# Define a character field for the author's name with a maximum length of 100 characters
author = models.CharField(max_length=100)
# Define a text field for the book description, which can be of variable length
description = models.TextField()
# Define an image field for the book cover. This field is optional (blank=True, null=True) and the images are stored in the 'covers/' directory
cover_image = models.ImageField(upload_to='covers/', blank=True, null=True)
# Meta class is where we provide special options to the model class
class Meta:
# Create indexes on the 'title' and 'author' fields to improve query performance
indexes = [
models.Index(fields=['title', 'author']),
]
# Define the __str__ method to tell Django what to display when it needs to represent an instance of the model as a string
def __str__(self):
return self.title # We choose to display the title of the book
title
:ACharField
表示书名,最大长度为 200 个字符。它很简洁,但对于大多数书名来说已经足够了。author
:另一个CharField
,这次是作者姓名,上限为 100 个字符。description
:ATextField
保存无限量的书籍描述文本。cover_image
:ImageField
存储封面图像。该upload_to
参数指定媒体存储中的子目录。和blank=True
参数null=True
指定该字段是可选的。在类中,我们为和字段Meta
定义数据库索引。对这些字段建立索引可以极大地加速搜索操作——就像教科书后面的快速参考索引一样,允许您跳到有关作者或标题的信息,而无需翻阅每一页。title
author
定义完成后,我们通过运行迁移将模型变为现实:
python manage.py makemigrations
python manage.py migrate
这告诉 Django 为我们的模型准备数据库表Book
,然后创建它,为我们的图书数据建立一个新家。
这样,我们的Book
模型就可以填充引人入胜的故事和知识了。它是一个结构化、高效的框架,就像一个坚固的书架,随时可以装满各种书籍,每本都准备好将读者带到另一个世界。
现在我们到了旅程的关键点:建立用户身份验证系统。正如图书馆需要一个系统来确保只有会员才能借阅书籍一样,我们的数字书架也需要一种识别和验证用户的机制。让我们为安全、稳健和友好的用户体验奠定基础。
自定义用户模型是灵活的身份验证系统的基石。它允许您从一开始就指定其他用户信息。将其视为设计一张真正适合您读书俱乐部独特需求的会员卡。
在 Django 中,我们能够根据应用程序的需求定制此模型。这是一个简单的自定义用户模型,它通过添加字段来扩展默认值nickname
:
# Import the AbstractUser class from Django's built-in authentication models
# This class provides the full implementation of the default User as an abstract model
from django.contrib.auth.models import AbstractUser
# Import the models module from Django to define our own models
from django.db import models
# Define our own CustomUser class that extends AbstractUser
# This allows us to add additional fields to the user model, while keeping all the base functionality
class CustomUser(AbstractUser):
# Add a new field 'nickname' to our user model
# It's a character field with a max length of 50 characters
# The 'blank=True' argument allows the field to be optional, so users don't need to provide a nickname
nickname = models.CharField(max_length=50, blank=True)
# Define the __str__ method to specify what to display when the model is printed
# In this case, we want to display the username of the user
def __str__(self):
return self.username # Returns the username of the CustomUser instance
并且不要忘记告诉 Django 你的新用户模型settings.py
:
# settings.py
AUTH_USER_MODEL = 'your_app.CustomUser'
自定义用户模型到位后,我们接下来实现安全登录和注册视图。可以使用 Django 的内置身份验证视图,但我们要确保它们已安全连接:
# Importing the built-in authentication views from Django to handle user login and logout
from django.contrib.auth import views as auth_views
# Importing the path function to define URL patterns
from django.urls import path
# Importing the views from the current directory to link to our custom view functions or classes
from . import views
# The urlpatterns list is where we define URL patterns to match incoming requests and route them to the appropriate view
urlpatterns = [
# Other URL patterns for the app would go here
# Define a URL pattern for the login page
# It uses Django's built-in LoginView, and we specify the template name to use for rendering the login form
path('login/', auth_views.LoginView.as_view(template_name='login.html'), name='login'),
# Define a URL pattern for the logout page
# It uses Django's built-in LogoutView and redirects the user to the homepage ('/') after logging out
path('logout/', auth_views.LogoutView.as_view(next_page='/'), name='logout'),
# Define a URL pattern for the registration page
# It uses a custom view function 'register' defined in the views.py file of the same directory
path('register/', views.register, name='register'),
# Other URL patterns for the app would go here
]
该register
视图将是您创建的用于处理新用户注册的自定义视图。
Django 带有一个强大的密码哈希系统,可以将密码转换为复杂的哈希值。这就像为每个密码创建一个密码,即使创建者也无法破译。这意味着如果有人接触到您的数据库,密码仍然安全。
Django 的身份验证系统为我们提供了开箱即用所需的一切,从用户会话到密码重置。这类似于拥有一流的安全系统,而无需您自己进行连接。
通过实现自定义用户模型并利用 Django 强大的身份验证系统,我们刚刚构建了一个安全、可扩展的基础来管理我们的用户。正如图书馆员了解他们的顾客一样,我们的应用程序现在可以识别其用户,并在我们正在创建的图书世界中为他们提供个性化、安全的体验。
进入下一阶段,我们将为我们的应用程序构建一个命令中心 - 一个管理界面。这是我们掌舵的舵,轻松而精确地管理内容和用户。
Django 管理站点是一个即用型界面,用于管理应用程序的内容。这就像您的数字书架有一个高级控制面板,只需单击一下即可添加、编辑或删除每本书。
Book
以下是向管理员注册模型的方法:
# Import the admin module from Django which is necessary to register our models with the Django admin interface
from django.contrib import admin
# Import the Book model from the local models.py file where it was defined
from .models import Book
# The @admin.register decorator is a Python decorator that registers the following class with the admin interface
# In this case, it's registering the Book model
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
# list_display is an attribute where we define which fields of the model to display in the admin list view
# Here, we want to show the title, author, and description of each book in the list
list_display = ('title', 'author', 'description')
# search_fields is an attribute where we define which fields should be searchable in the admin's search box
# We're making the title and author fields searchable
search_fields = ('title', 'author')
在BookAdmin
类中,我们指定在列表视图中显示哪些字段以及哪些字段应该可搜索,将管理界面变成图书管理的强大工具。
处理表单时,安全性至关重要。我们必须确保每条数据在我们的数据库中找到归属之前都经过仔细审查。DjangoModelForm
使这变得更容易:
# Import the forms module from Django which provides a way of defining form behavior
from django import forms
# Import the Book model from the local models.py file which defines the structure of book records in the database
from .models import Book
# Define a new class called BookForm which is a ModelForm, a special kind of Django form that is tied to a database model
class BookForm(forms.ModelForm):
# Inside the class, we create a nested class named Meta
# This Meta class tells Django which model the form is based on and which fields should be included in the form
class Meta:
# Specify the model that this form is linked to
model = Book
# List the fields from the model that we want to include in our form
fields = ['title', 'author', 'description', 'cover_image']
这BookForm
确保了仅接受指定的字段,并且每个输入都由 Django 的内置机制进行清理和验证。这就像有一位细心的图书管理员在将每本书放在书架上之前对其进行检查。
Django 附带了一套旨在防止常见 Web 攻击的安全功能。CSRF 令牌、安全密码存储和点击劫持保护只是我们可以使用的一些工具。通过遵循 Django 的最佳实践,我们正在增强我们的应用程序免受潜在威胁的能力,就像银行金库保护其资产的方式一样。
随着管理界面的到位和安全的表单处理流程的建立,我们拥有了一个强大的数据管理系统。就好像我们不仅建造了一个书架,还建造了一张图书管理员的办公桌,配有账本和锁,确保我们的藏书得到安全有效的管理。
当我们进入 Web 应用程序的核心时,是时候塑造用户与我们精选的集合交互的方式了。我们将制作视图和模板——展示和路径,引导我们的访客浏览我们收集的图书库。
Django 中基于类的视图就像拥有一组常见 Web 开发模式的蓝图。它们功能强大且可重用,降低了代码的复杂性并增强了可维护性。想象一下,拥有一把通往建筑物中各个房间的主钥匙,每个房间都有特定的用途。
以下是我们如何实现书籍的列表视图和详细视图的一瞥:
# Import Django's generic ListView and DetailView classes which are handy for displaying a list of objects and the details of a specific object, respectively
from django.views.generic import ListView, DetailView
# Import the Book model from the local models.py file to be used in these views
from .models import Book
# Define a class-based view called BookListView, which inherits from ListView
# This view will be used to display a list of all the books
class BookListView(ListView):
model = Book # Tell Django which model to use for listing objects; in this case, it's the Book model
template_name = 'books/book_list.html' # Specify the path to the template that renders the book list
context_object_name = 'book_list' # Define the context variable name that will be used in the template to access the list of books
# Define a class-based view called BookDetailView, which inherits from DetailView
# This view will be used to display the details of a specific book
class BookDetailView(DetailView):
model = Book # Specify the model to use for detail view; again, it's the Book model
template_name = 'books/book_detail.html' # Specify the path to the template that renders the details of a book
context_object_name = 'book' # Define the context variable name to be used in the template to access the book object
这些视图连接到模板,这些模板将以用户友好的格式呈现信息。它BookListView
提供了书籍目录,而BookDetailView
在选择时重点关注单本书的具体细节。
Django 中的模板不仅仅是 HTML;它们是显示数据的安全方式。Django 模板会自动转义变量以防止注入攻击,就像一个盾牌可以偏转任何瞄准我们应用程序核心的有害箭头。
{% for book in book_list %}
{{ book.title }}
{{ book.author }}
{{ book.description|truncatewords:30 }}
{% empty %}
No books available.
{% endfor %}
模板中的过滤truncatewords
器确保长描述不会淹没页面,展示了 Django 模板语言保持数据呈现整洁和安全的能力。
为了让用户能够搜索我们的集合,我们可以BookListView
使用简单的查询过滤器来扩展:
# views.py (Continuation)
class BookListView(ListView):
# ... (existing attributes and methods of BookListView)
# Overriding the get_queryset method to customize the list of books that will be returned
def get_queryset(self):
# First, we get the default queryset of the Book model by calling super().get_queryset()
# This default queryset would return all books in the database
queryset = super().get_queryset()
# We attempt to retrieve a value from the request's GET parameters with the key 'q'
# The 'q' parameter will hold our search term. If it's not present, we default to an empty string
search_query = self.request.GET.get('q', '')
# If there is a search query (the string is not empty),
# we filter the queryset to only include books with titles that contain the search term
if search_query:
# The filter method narrows down the queryset based on the given criteria.
# title__icontains is a Django query that is case-insensitive (i for insensitive) and looks for the search_query anywhere within the book title (contains)
queryset = queryset.filter(title__icontains=search_query)
# The possibly modified queryset is returned.
# If there was a search term, it's now a filtered list of books that match the term; otherwise, it's all books
return queryset
通过在我们的模板中添加搜索栏book_list.html
,用户现在可以轻松地按标题搜索书籍。
借助基于类的视图、安全模板和一些搜索魔法,我们刚刚为无缝用户体验铺平了道路。这就像我们为每位游客安排了一次私人游览,引导他们穿过一排排书架,每个书架上都充满了等待发现的故事。我们的数字书架不仅仅是书籍的存储库;这是一个井井有条、安全且温馨的迷人空间,是图书爱好者真正的天堂。
当我们进一步深入研究应用程序架构时,是时候通过中间件增强和性能优化来加固墙壁并简化走廊了。这是我们增加保护层和效率的地方,以确保为用户提供无缝和安全的体验。
Django 中的中间件类似于戒备森严的堡垒中的各个检查站。它们被战略性地放置来检查和过滤传入和传出的流量。通过设置安全标头,我们为应用程序添加了一组防护,使其免受常见 Web 漏洞的影响。
以下是我们如何在文件中设置其中一些标头的示例settings.py
:
# settings.py
MIDDLEWARE = [
# ... (other middleware)
'django.middleware.security.SecurityMiddleware',
# ... (other middleware)
]
SECURE_BROWSER_XSS_FILTER = True
X_CONTENT_TYPE_OPTIONS = 'nosniff'
SECURE_CONTENT_TYPE_NOSNIFF = True
这些设置指示浏览器激活针对某些 Web 攻击(例如跨站点脚本和“mime”类型嗅探)的内置保护。
缓存就像一位聪明的老图书管理员的记忆,他可以准确地记住每本书的位置,而无需查找。通过实施缓存,我们允许我们的应用程序记住经常访问的数据,从而加快响应时间。
Django 提供了一个强大的缓存框架,可以按如下方式使用:
# settings.py
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}
这LocMemCache
是Django提供的最简单的缓存后端,将数据存储在Django运行的进程的内存中。
对于更具可扩展性的解决方案,您可以考虑使用专用缓存系统,例如 Redis 或 Memcached,可以在您的settings.py
.
最后,我们可以通过确保有效地使用 Django 的 ORM 来优化数据库查询。
在这里查看 Google 最好的 ORM 技术
通过使用中间件安全增强功能和采用缓存策略来增强我们的应用程序,我们不仅增强了应用程序抵御外部威胁的能力,还优化了其性能。数据传输的走廊现在更加高效,确保每条信息的传输更快、更安全。
这种在后台工作的无声机器使用户体验流畅可靠,就像翻阅一本装订精良的书页的无缝体验一样。
在我们的 Web 应用程序的剧场中,媒体和静态文件类似于为令人难忘的表演搭建舞台的背景和服装。当我们向观众展示我们的创作时,确保有效地传递这些元素至关重要。正是在这里,WhiteNoise 介入,就像一位熟练的舞台监督,确保每个脚本和样式表都优雅而快速地进入。
WhiteNoise 是一个实用程序,它可以为我们的 Django 应用程序提供直接服务静态文件的能力,从而无需在生产中为此目的而使用单独的 Web 服务器。当我们的应用程序的性能至关重要时,这尤其方便(我们在步骤 2 中执行此操作,但在这里我将详细解释它们)。
要集成 WhiteNoise,我们从简单的安装开始:
pip install whitenoise
接下来,我们更新我们的代码settings.py
以欢迎 WhiteNoise 加入中间件集成:
# settings.py
MIDDLEWARE = [
# ... other middleware classes
'whitenoise.middleware.WhiteNoiseMiddleware', # Adds WhiteNoise to our array of middlewares
# ... other middleware classes
]
# Configure static files settings, integrating WhiteNoise for serving static files in production
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') # Define the directory for collected static files
STATICFILES_DIRS = ( # Additional locations for static files
os.path.join(BASE_DIR, 'static'),
)
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' # WhiteNoise storage for static files
此设置使 WhiteNoise 能够有效地管理静态文件、压缩它们并设置缓存标头以优化交付。
在我们的应用程序成为众人瞩目的焦点之前,我们需要将所有静态部分收集到一个地方,为性能做好准备。这就是collectstatic
命令发挥作用的地方,类似于彩排,确保每个元素都就位。
python3 manage.py collectstatic
此命令提示 Django 从我们的应用程序和我们正在使用的任何第三方应用程序收集所有静态文件,并将它们放入目录中STATIC_ROOT
。然后,WhiteNoise 将从这里开始,将这些文件视为其脚本来协调交付。
虽然静态文件保持不变,但媒体文件是我们游戏中的动态角色,由用户上传和修改。它们需要小心处理:
# settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
这些设置可确保用户生成的内容拥有自己的专用空间并得到正确管理。
如果现场座无虚席,内容交付网络 (CDN) 可确保观众中的任何用户都不会等待。WhiteNoise 优雅地将接力棒传递给 CDN,确保静态文件不仅得到有效的服务,而且在地理上分布以提高性能:
# settings.py
CDN_URL = 'https://mycdn.example.com' # This is the base URL provided by your CDN service
STATIC_URL = CDN_URL + '/static/' # This sets up the full URL for serving static files
借助 WhiteNoise 和collectstatic
Harmony,以及广泛传播我们内容的 CDN,我们的应用程序已准备好占据中心舞台。每个用户的请求都会得到快速交付,确保体验就像精心排练的开幕之夜一样无缝和专业。我们的数字幕布升起,演出开始。
当我们的 Web 应用程序开发交响曲接近高潮时,我们将注意力转向虚拟专用服务器 (VPS) 上的严格测试、部署和监控过程。是时候确保我们的创作不仅在开发的排练空间中而且在制作的明亮灯光下完美地表现。
在我们的应用程序进入生产阶段之前,它必须经过一系列的彩排 - 测试。我们编写场景并编写测试用例来模仿未来受众(用户)的行为和交互。这种尽职尽责就像一个一丝不苟的导演,没有一句台词是不练习的,没有一个场景是不经过修饰的。
# tests.py
from django.test import TestCase
from .models import Book
class BookModelTest(TestCase):
@classmethod
def setUpTestData(cls):
Book.objects.create(title='Test Book', author='Test Author')
def test_title_content(self):
book = Book.objects.get(id=1)
expected_object_name = f'{book.title}'
self.assertEqual(expected_object_name, 'Test Book')
我已经创建了一个关于如何部署 Django 应用程序的分步课程,为了避免这篇文章太长,我将其留在这里
Web 服务器的舞台工作人员:Gunicorn:
Gunicorn 充当我们生产环境的舞台工作人员,它是一个可靠的 WSGI HTTP 服务器,为我们的应用程序注入了生命力,使其能够为世界各地的观众表演。配置 Gunicorn 很简单,但对于强大的生产设置至关重要。
Nginx 是经验丰富的舞台管理器,作为反向代理在幕后不知疲倦地工作,管理和引导网络流量,确保每个请求都能顺利到达 Gunicorn。它与 Gunicorn 一起创建了一个无缝的生产环境。
SSL 加密相当于安全剧院,观众和表演者之间的每一次对话都受到保护。这种加密可确保交换的数据保密且防篡改。
随着该应用程序现已掌握在公众手中,监控工具就像细心的引座员一样,密切关注表演。用于错误跟踪的 Sentry 或用于监控的 Prometheus 等工具对于确保万一出现问题,可以在对观众造成最小干扰的情况下重置场景至关重要。
随着我们通过 10 个综合步骤构建安全且高性能的 Django Web 应用程序的旅程最终落下帷幕,我们可以反思一下用于制作这一数字杰作的一系列工具和技术。从基础设置到完善的部署,每一步都是我们 Web 应用程序挂毯中一丝不苟的线索。