首页
开发技巧正文内容

10个步骤构建一个安全且高性能的Django Web应用程序

2023年11月09日
阅读时长 2 分钟
阅读量 12
10个步骤构建一个安全且高性能的Django Web应用程序

深入研究如何构建一个安全、高效的Django应用程序

从设置到部署,我们将为强大的高性能Web体验提供全面的覆盖。

Photo by Teemu Paananen on Unsplash

开始构建一个Web应用程序不仅需要对编码和设计原则有深入的理解,还需要对安全性和性能有坚定的承诺。在数字存在至关重要的时代,构建一个强大而高效的在线平台的能力是一项无法估量的技能。本教程致力于网络艺术家,那些希望将技术的线索编织成功能和安全性的织锦的人。

我们的努力将是以一种有条不紊的方式进行的,分为十个基础步骤。每一步都是一个里程碑,标志着我们从零开始雕刻应用程序的进展。

第一步:环境设置和项目初始化

我们通过配置开发环境来奠定项目的基石,将我们的工作空间封装在一个虚拟的信封中,使我们应用程序的依赖关系可以和谐地共存,免受外部冲突的影响。

第二步:应用程序设置和初始配置

就像在一场盛大的表演之前布置舞台一样,我们在应用程序中的早期阶段就配置它,以符合安全性的要求和高性能的需求。

第三步:安全数据库配置

应用程序数据的完整性至关重要。我们将集成PostgreSQL,以确保我们的数据安全地存储在一个坚固的堡垒中,不受外部威胁的侵害。

第四步:构建图书模型

在这里,我们定义应用程序的核心 - 图书模型 - 通过精心构建的数据字段捕捉每一卷所包含的丰富知识。

第五步:用户身份验证系统

信任是网络的货币。我们将打造一个身份验证系统,不仅验证身份,还以坚定的勤勉维护用户信息的机密性。

第六步:管理员界面和安全数据管理

随着管理员被赋予的权力,管理数据的责任也随之而来,需要精确和保护。我们的管理员界面将成为这种平衡的证明。

第七步:实现视图和模板

视图和模板是用户感知我们应用程序的镜头。我们将以美学和安全数据表示为目标来精心制作它们。

第八步:中间件增强和性能优化

我们应用程序的中间件将作为无声的守护者,执行安全策略和缓存策略,以确保无缝和快速的用户体验。

第九步:媒体和静态文件配置

当我们准备将应用程序展示给世界时,我们要确保每个图像、每个样式表都能高效地传递,可能利用内容分发网络的强大功能。

第十步:在VPS上进行测试、部署和监控

当我们接近努力的顶峰时,我们将对应用程序进行彻底的测试,将其部署到强大的虚拟专用服务器上,并设置持续监控。这样可以确保它在与真实世界互动时保持响应和弹性。

请记住,打造我们的Web应用程序的冒险与精心打磨的产品本身一样有意义。每一步都是对提高技能和加深理解的友好提示。通过克服每一个挑战所获得的知识才是任何开发者旅程的真正回报。让我们开始吧。

第一步:环境设置和项目初始化

将开发环境想象成您的个人工作室。就像木匠不希望一个项目的锯末干扰另一个项目一样,我们使用Python中的虚拟环境来保持我们项目的库和依赖关系在自己整洁的小空间中。

创建虚拟环境

让我们开始并在虚拟环境中设置我们的工作空间。这只是在终端中执行一系列命令。对于Linux或macOS,操作如下:

python3 -m venv myenv
source myenv/bin/activate

对于Windows,您将输入:

python -m venv myenv
myenv\Scripts\activate

当您在命令提示符之前看到您的环境名称(myenv)在括号中时,您就知道它已经起作用了。

安装Django

激活我们的环境后,是时候将Django引入其中了。Django只需一个pip命令即可:

pip install django

有了这个,Django就在我们的命令下,准备帮助我们构建一些令人惊叹的东西。

创建项目骨架

现在,让我们召唤Django的魔力来创建我们项目的骨架,就像搭建建筑物的基础和框架一样:

django-admin startproject my_awesome_bookstore

进入您的新项目文件夹:

cd my_awesome_bookstore

这样我们就有了一个坚实的基础,准备迅速行动的Web应用程序。在这一初始步骤中,我们创建了一个干净的工作区,完全具备自己的虚拟环境。

我们邀请Django加入我们的工具包,并展开我们的Web应用程序的架构计划。这有点像搭建一个新的工作室,一切都井然有序,标记清晰,准备迎接数字书店开业的第一天。您已经迈出了创造力和学习的第一步 - 这个过程一定会像您打开数字书店大门的那一天一样有意义。

第二步:应用程序设置和初始配置

创建我们的第一个应用程序:

将您的Django项目想象成一个繁华的城镇,您的应用程序就是填充其中的商店和服务。现在是时候建立我们的第一个机构了。在终端中,激活虚拟环境并进入项目目录,运行以下命令:

python manage.py startapp bookshelf

这个命令创建了一个新的“bookshelf”应用程序 - 我们在数字城镇中展示图书的舒适角落。

调整设置的螺栓和螺母:

现在,让我们为我们的应用程序提供坚固的门和可靠的报警系统。在项目目录中打开settings.py文件。这个文件就像我们应用程序的控制面板,我们将在这里调整一些杠杆和旋钮,以增强安全性和性能(关于其中一些我们稍后会讲到)。

# settings.py

# 导入os模块以进行路径设置
import os

# ...(其他设置在上面)

# 当您上线时,关闭调试模式非常重要。这样可以防止错误消息中显示敏感信息。
DEBUG = False

# 这里列出了您的Django站点可以提供的主机/域名。这是一项安全措施,用于防止HTTP Host头攻击。
ALLOWED_HOSTS = ['daniel.com', 'www.daniel.com']

# 数据库
DATABASES = {
    'default': {
        # 我们指定后端
        'ENGINE': 'django.db.backends.postgresql',
        # 数据库名称
        'NAME': 'mydatabase',
        # 数据库用户应该是唯一的,用于安全目的。
        'USER': 'myuser',
        # 数据库用户的密码。保持秘密!
        'PASSWORD': 'mypassword',
        # 数据库服务器运行的主机 - 通常是单服务器设置的localhost。
        'HOST': 'localhost',
        # 数据库侦听的端口号。通常设置为数据库的默认端口。
        'PORT': '',
    }
}

# 设置缓存。即使是简单的本地内存缓存也可以通过将频繁访问的数据存储在内存中来提高性能。
CACHES = {
    'default': {
        # 使用本地内存缓存后端,它快速且适用于单进程环境。
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        # 此缓存实例的唯一名称。就像在仓库中给一个箱子贴上标签,以便以后可以轻松找到它一样。
        'LOCATION': 'unique-snowflake',
    }
}

# 配置静态文件设置,集成WhiteNoise以在生产环境中提供静态文件
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')  # 定义收集的静态文件的目录
STATICFILES_DIRS = (  # 静态文件的其他位置
    os.path.join(BASE_DIR, 'static'),
)
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'  # WhiteNoise静态文件存储

# 媒体文件配置
MEDIA_URL = '/media/'

# 我们将始终使用HTTPS来确保我们应用程序的聊天是VIP专属的,将每一次对话都变成私密的加密耳语。
SECURE_SSL_REDIRECT = True  # 将所有非HTTPS请求重定向到HTTPS
SESSION_COOKIE_SECURE = True  # 确保仅通过HTTPS发送cookie
CSRF_COOKIE_SECURE = True  # 确保CSRF cookie仅通过HTTPS发送

# 通过防止Django站点在框架或iframe中呈现来防止点击劫持。
X_FRAME_OPTIONS = 'DENY'# 将WhiteNoise添加到中间件以高效地提供静态文件

MIDDLEWARE = [
    # ...(其他中间件条目)
    'whitenoise.middleware.WhiteNoiseMiddleware',
    # ...(其他中间件条目)
]

# ...(其余设置)

让我们使用WhiteNoise来管理静态文件,同时使用PostgreSQL数据库来提高性能,使我们的Django应用程序准备好迎接光芒。就像指挥家为交响乐团做准备一样,我们将调整settings.py并添加一些额外的包,以确保一切都能很好地协同工作。

所以,拿起你的pip魔杖,让我们安装那些能让我们的应用程序更出色的包。这里是一个小指南,告诉你我们将要做什么以及为什么它会让我们的应用程序更出色。确保你已经激活了你的虚拟环境:

# 对于类Unix系统(Linux/macOS)
pip install django psycopg2-binary Whitenoise

# 对于Windows系统
pip install django psycopg2 Whitenoise

psycopg2-binary包是一个独立的包,适用于类Unix系统,它包含了psycopg2 PostgreSQL适配器,并跳过了对任何外部依赖的需求。在Windows上,我们安装的是PostgreSQL适配器本身的psycopg2

通过将DEBUG设置为False并配置ALLOWED_HOSTS,我们确保没有意外的信息泄露,并且我们的应用程序确切地知道它的位置。集成PostgreSQL为我们提供了一个强大的数据库,设置一个简单的缓存策略可以使页面加载迅速。

这只是个开始。随着我们应用程序的旅程展开和我们的数字社区蓬勃发展,我们将打开引擎盖,调整我们的设置,根据用户社区的不断增长的脉搏进行定制。

通过这些初始调整,我们的应用程序已经准备好进入数字世界。对于应用程序来说,这是一个小步骤,但对于我们的项目来说,这是一个巨大的飞跃!这有点像打开一家新店的大门——油漆新鲜,货架坚固,我们准备好欢迎访客。我们的书架应用程序已经准备好成为我们Django项目繁忙城镇中受人喜爱的一站。

第3步:安全的数据库配置

现在,是时候为我们应用程序的宝贵数据打造一个安全的角落了。我们将把它们全部放入PostgreSQL中,这是一个像古老的橡木一样坚固可靠的数据库。这是我们的信息称之为家的完美数字堡垒。但我们不会止步于此——我们还将通过使用环境变量来存储我们的数据库凭据来实施关键的安全实践。

让我们为我们的应用程序设置一个舒适的数据库。想象一下PostgreSQL是一个可信的图书馆,我们应用程序的所有故事都安全、完好无损地存放在那里,整齐地摆放在书架上。这就是每一章用户数据都在书架上找到一个舒适的位置,这要归功于PostgreSQL在安全性和性能方面的卓越声誉。

想象一下,如果有人把这个图书馆的钥匙放在了门口的欢迎垫子下面。不太明智,对吧?这正是为什么我们不会只是在代码中涂抹我们的数据库访问秘密。相反,我们将它们藏在环境变量中,就像魔术师斗篷中的一个秘密口袋一样,远离窥探的眼睛。

下面是如何将你的settings.py转换为从这些环境变量中提取数据库设置的方法:

# settings.py
import os
from dotenv import load_dotenv

# 初始化dotenv库以加载.env文件
load_dotenv()

# ...(其他设置)

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('DB_NAME', 'mydatabase'),  # 如果找不到,默认值
        'USER': os.environ.get('DB_USER', 'myuser'),      # 如果找不到,默认值
        'PASSWORD': os.environ.get('DB_PASSWORD'),        # 没有默认值,必须设置
        'HOST': os.environ.get('DB_HOST', 'localhost'),   # 如果找不到,默认值
        'PORT': os.environ.get('DB_PORT', ''),            # 如果找不到,默认值
    }
}

# ...(其他设置)

你将把数据库凭据存储在项目根目录下的.env文件中,不要将其提交到版本控制系统(例如Git):

# .env文件
DB_NAME=mydatabase
DB_USER=myuser
DB_PASSWORD=securepassword123
DB_HOST=localhost
DB_PORT=5432

通过使用环境变量,我们创建了一个灵活且安全的配置,将敏感信息保持在代码库之外。这就像有一个只有你的应用程序和你的数据库知道的秘密握手。

现在,PostgreSQL作为我们的数据层的支柱,环境变量作为我们的秘密保管者,我们已经加固了我们应用程序的基础设施。它已经准备好接收我们的“书架”将要容纳的丰富信息,远离窥探的眼睛,为性能做好准备。

第4步:构建Book模型

现在,让我们转向打造我们数字书架的精髓——Book模型。这个模型是我们如何在数据库中存储与书籍相关的数据的蓝图,就像图书管理员对书籍进行分类以便于查找一样。

定义Book模型:

在Django的世界中,模型是关于你的数据的唯一真相来源。它们包含了你存储的数据的基本字段和行为。Django遵循DRY原则(不要重复自己),因此每个信息只定义一次。

这是我们的Book模型在我们的书架应用程序的models.py文件中可能是什么样子的一个例子:

# 从Django的内置认证模型中导入models模块,以定义我们的数据库模式为Python类
from django.db import models

# 定义一个名为Book的新类,它是一个Django模型,意味着它将在数据库中表示为一个表
class Book(models.Model):
    # 为书名定义一个字符字段,最大长度为200个字符
    title = models.CharField(max_length=200)
    # 为作者的名字定义一个字符字段,最大长度为100个字符
    author = models.CharField(max_length=100)
    # 为书籍描述定义一个文本字段,它可以是可变长度的
    description = models.TextField()
    # 为书籍封面定义一个图像字段。该字段是可选的(blank=True, null=True),并且图像存储在'covers/'目录中
    cover_image = models.ImageField(upload_to='covers/', blank=True, null=True)

    # Meta类是我们为模型类提供特殊选项的地方
    class Meta:
        # 在'title'和'author'字段上创建索引以提高查询性能
        indexes = [
            models.Index(fields=['title', 'author']),
        ]

    # 定义__str__方法,告诉Django在需要将模型实例表示为字符串时显示什么
    def __str__(self):
        return self.title  # 我们选择显示书的标题

模型字段和索引的解释:

  • title:一个CharField,用于书名,最大长度为200个字符。它简洁但足够大多数书名使用。

  • author:另一个CharField,这次是作者的名字,最多100个字符。

  • description:一个TextField,用于保存书籍的描述的不限长度的文本。

  • cover_image:一个ImageField,用于存储封面图片。upload_to参数指定了媒体存储中的子目录。blank=Truenull=True参数指定该字段是可选的。

为了性能而建立索引:

Meta类中,我们为titleauthor字段定义了数据库索引。为这些字段建立索引可以极大地加速搜索操作——就像教科书后面的快速参考索引一样,可以让你在不翻阅每一页的情况下跳转到关于作者或标题的信息。

将模型实例化:

一旦定义好,我们通过运行迁移来实例化我们的模型:

python manage.py makemigrations
python manage.py migrate

这告诉Django为我们的Book模型准备数据库表,然后创建它,为我们的书籍数据建立一个新的家。

有了这个,我们的Book模型就准备好填充引人入胜的故事和知识了。它就像一个结构化、高效的框架,就像一个坚固的书架,准备好填充各种各样的书籍,每一本书都准备好将读者带到另一个世界。

第5步:用户认证系统

现在,我们来到了我们旅程的关键点:建立一个用户认证系统。就像图书馆需要一个系统来确保只有会员可以借书一样,我们的数字书架需要一个机制来识别和验证用户。让我们为一个安全、强大和友好的用户体验做好准备。

构建一个自定义用户模型:

自定义用户模型是灵活的身份验证系统的基石。它允许您从一开始就指定额外的用户信息。把它看作是设计一个真正适合您的书籍俱乐部独特需求的会员卡。

在Django中,我们有能力根据我们应用程序的需求来定制这个模型。这是一个简单的自定义用户模型的例子,它通过添加一个nickname字段来扩展默认模型:

# 从Django的内置认证模型中导入AbstractUser类
# 这个类提供了默认用户的完整实现作为一个抽象模型
from django.contrib.auth.models import AbstractUser
# 从Django中导入models模块来定义我们自己的模型
from django.db import models

# 定义我们自己的CustomUser类,它扩展了AbstractUser
# 这允许我们在用户模型中添加额外的字段,同时保留所有基本功能
class CustomUser(AbstractUser):
    # 向我们的用户模型添加一个新字段'nickname'
    # 它是一个字符字段,最大长度为50个字符
    # 'blank=True'参数允许该字段是可选的,所以用户不需要提供昵称
    nickname = models.CharField(max_length=50, blank=True)# 定义__str__方法来指定在打印模型时要显示的内容
    # 在这种情况下,我们希望显示用户的用户名
    def __str__(self):
        return self.username  # 返回CustomUser实例的用户名

并且不要忘记在settings.py中告诉Django你的新用户模型:

# settings.py

AUTH_USER_MODEL = 'your_app.CustomUser'

实现安全的登录和注册:

有了自定义用户模型,我们接下来实现安全的登录和注册视图。Django内置的身份验证视图可以使用,但让我们确保它们被安全地连接起来:

# 从Django导入内置的身份验证视图来处理用户登录和注销
from django.contrib.auth import views as auth_views
# 从django.urls导入path函数来定义URL模式
from django.urls import path
# 从当前目录导入视图以链接到我们自定义的视图函数或类
from . import views

# urlpatterns列表是我们定义URL模式的地方,用于匹配传入的请求并将其路由到适当的视图
urlpatterns = [
    # 应用程序的其他URL模式将放在这里

    # 为登录页面定义一个URL模式
    # 它使用Django的内置LoginView,并指定要用于呈现登录表单的模板名称
    path('login/', auth_views.LoginView.as_view(template_name='login.html'), name='login'),

    # 为注销页面定义一个URL模式
    # 它使用Django的内置LogoutView,并在注销后将用户重定向到主页('/')
    path('logout/', auth_views.LogoutView.as_view(next_page='/'), name='logout'),

    # 为注册页面定义一个URL模式
    # 它使用在同一目录的views.py文件中定义的自定义视图函数'register'
    path('register/', views.register, name='register'),

    # 应用程序的其他URL模式将放在这里
]

register视图将是您创建的用于处理新用户注册的自定义视图。

保护密码:

Django提供了一个强大的密码哈希系统,将密码转换为复杂的哈希值。这就像为每个密码创建一个秘密代码,即使是创建者也无法解密。这意味着如果有人拿到了您的数据库,密码仍然是安全的。

利用Django的内置身份验证系统:

Django的身份验证系统为我们提供了一切所需的功能,从用户会话到密码重置。这就像在不需要自己连接的情况下拥有一个一流的安全系统。

通过实现自定义用户模型并利用Django强大的身份验证系统,我们刚刚建立了一个安全、可扩展的用户管理基础。就像图书管理员了解他们的读者一样,我们的应用程序现在可以识别其用户,并为他们在我们正在创建的图书世界中提供个性化、安全的体验。

第6步:管理界面和安全数据管理

进入下一个阶段,我们将为我们的应用程序构建一个指挥中心 - 管理界面。这是我们将以轻松和精确的方式管理内容和用户的舵。

使用Django Admin轻松管理图书:

Django admin网站是一个可用于管理应用程序内容的即用型界面。它就像是为您的数字书架提供了一个先进的控制面板,每本书都只需点击即可添加、编辑或删除。

以下是如何将Book模型注册到admin中的示例:

# 从Django导入admin模块,这是将我们的模型注册到Django admin界面所必需的
from django.contrib import admin
# 从本地的models.py文件中导入Book模型
from .models import Book

# @admin.register装饰器是一个Python装饰器,用于将以下类注册到admin界面
# 在这种情况下,它注册了Book模型
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    # list_display是一个属性,我们在其中定义要在admin列表视图中显示的模型字段
    # 在这里,我们希望在列表中显示每本书的标题、作者和描述
    list_display = ('title', 'author', 'description')

    # search_fields是一个属性,我们在其中定义哪些字段应该在admin的搜索框中可搜索
    # 我们将标题和作者字段设置为可搜索
    search_fields = ('title', 'author')

BookAdmin类中,我们指定要在列表视图中显示哪些字段,以及哪些字段应该是可搜索的,将admin界面变成一个强大的图书管理工具。

安全的表单处理:

在处理表单时,安全性至关重要。我们必须确保每个数据片段在进入数据库之前都经过仔细检查。Django的ModelForm使这变得更容易:

# 从Django导入forms模块,它提供了一种定义表单行为的方法
from django import forms
# 从本地的models.py文件中导入Book模型,该模型定义了数据库中书籍记录的结构
from .models import Book

# 定义一个名为BookForm的新类,它是一个ModelForm,一种特殊的Django表单,与数据库模型相关联
class BookForm(forms.ModelForm):
    # 在类内部,我们创建了一个名为Meta的嵌套类
    # 这个Meta类告诉Django该表单基于哪个模型,以及应该在表单中包含哪些字段
    class Meta:
        # 指定此表单所关联的模型
        model = Book
        # 列出我们想在表单中包含的模型字段
        fields = ['title', 'author', 'description', 'cover_image']

这个BookForm确保只接受指定的字段,并且Django的内置机制会清理和验证每个输入。就像有一个细致入微的图书管理员,在将每本书放在书架上之前对其进行检查。

利用Django的安全功能:

Django提供了一套安全功能,旨在防止常见的Web攻击。CSRF令牌、安全密码存储和点击劫持保护只是我们可以使用的一些工具。通过遵循Django的最佳实践,我们正在加固我们的应用程序,使其免受潜在威胁,就像银行保险库保护其资产一样。

通过建立管理界面和建立安全的表单处理流程,我们拥有了一个强大的数据管理系统。就像我们不仅建立了一个书架,还建立了一个图书管理员的办公桌,里面有一个账本和一个锁,确保我们的收藏得到安全和高效的管理。

第7步:实现视图和模板

当我们驶入我们的Web应用程序的核心时,是时候塑造用户与我们精心策划的收藏之间的互动方式了。我们将创建视图和模板 - 展示和引导我们的访问者穿越我们组装的图书馆的展示和路径。

利用基于类的视图:

Django中的基于类的视图就像拥有一套常见Web开发模式的蓝图。它们强大且可重用,减少了代码的复杂性,增强了可维护性。想象一下拥有一把通往建筑物中各个房间的万能钥匙,每个房间都设计用于特定的目的。

以下是我们如何为图书实现列表视图和详细视图:

# 从Django导入通用的ListView和DetailView类,它们非常适合显示对象列表和特定对象的详细信息
from django.views.generic import ListView, DetailView
# 从本地的models.py文件导入Book模型,以在这些视图中使用
from .models import Book

# 定义一个名为BookListView的基于类的视图,它继承自ListView
# 这个视图将用于显示所有书籍的列表
class BookListView(ListView):
    model = Book  # 告诉Django要使用哪个模型来列出对象;在这种情况下,是Book模型
    template_name = 'books/book_list.html'  # 指定用于呈现书籍列表的模板的路径
    context_object_name = 'book_list'  # 定义在模板中用于访问书籍列表的上下文变量的名称

# 定义一个名为BookDetailView的基于类的视图,它继承自DetailView
# 这个视图将用于显示特定书籍的详细信息
class BookDetailView(DetailView):
    model = Book  # 指定用于详细视图的模型;同样,是Book模型
    template_name = 'books/book_detail.html'  # 指定用于呈现书籍详细信息的模板的路径
    context_object_name = 'book'  # 定义在模板中用于访问书籍对象的上下文变量的名称

这些视图与将呈现信息的模板连接在一起。BookListView提供了书籍的目录,而BookDetailView则专注于选择的单本书的细节。

保护模板:

在Django中,模板不仅仅是HTML;它们是一种安全的显示数据的方式。Django模板会自动转义变量,以防止注入攻击,就像一个盾牌,防止任何有害的箭矢瞄准我们应用程序的核心。

<!-- book_list.html -->

{% for book in book_list %}
  <h2><a href="{{ book.get_absolute_url }}">{{ book.title }}</a></h2>
  <p>{{ book.author }}</p>
  <p>{{ book.description|truncatewords:30 }}</p>
{% empty %}
  <p>No books available.</p>
{% endfor %}

模板中的truncatewords过滤器确保长描述不会淹没页面,展示了Django模板语言的数据呈现整洁和安全的能力。

启用搜索功能:

为了让用户能够搜索我们的收藏,我们可以通过简单的查询过滤器扩展我们的BookListView

# views.py(续)

class BookListView(ListView):
    # ...(BookListView的现有属性和方法)# 重写get_queryset方法以自定义返回的书籍列表
    def get_queryset(self):
        # 首先,通过调用super().get_queryset()获取Book模型的默认查询集
        # 这个默认查询集将返回数据库中的所有书籍
        queryset = super().get_queryset()
        
        # 我们尝试从请求的GET参数中使用键'q'检索一个值
        # 'q'参数将保存我们的搜索词。如果不存在,默认为空字符串
        search_query = self.request.GET.get('q', '')
        
        # 如果存在搜索词(字符串不为空),
        # 我们将查询集筛选为只包含标题中包含搜索词的书籍
        if search_query:
            # filter方法根据给定的条件缩小查询集。
            # title__icontains是一个Django查询,它是不区分大小写的(i表示不区分大小写),并在书籍标题中查找搜索词(包含)
            queryset = queryset.filter(title__icontains=search_query)
        
        # 返回可能已修改的查询集。
        # 如果存在搜索词,现在它是一个匹配该词的书籍的筛选列表;否则,它是所有书籍
        return queryset

通过在book_list.html模板中添加搜索栏,用户现在可以轻松地按标题搜索书籍。

通过类视图、安全的模板和一点搜索魔法,我们为无缝的用户体验铺平了道路。就像我们为每个访客安排了一次私人导览,引导他们穿过一排排书架,每个书架都装满了等待被发现的故事。我们的数字书架不仅仅是书籍的存储库;它是一个有组织、安全和热情的空间,真正是书迷的避风港。

第8步:中间件增强和性能优化

随着我们深入应用程序的架构深处,现在是时候加强墙壁并优化走廊,以增强中间件和性能优化。这是我们为用户提供无缝和安全体验所添加的保护和效率层。

通过中间件加强安全性:

在Django中,中间件类似于一个设施完备的堡垒中的各个检查点。它们被策略性地放置以检查和过滤进出的流量。通过设置安全头,我们为应用程序添加了一套盔甲,保护它免受常见的Web漏洞。

以下是我们如何在settings.py文件中设置一些这些头的示例:

# settings.py

MIDDLEWARE = [
    # ...(其他中间件)
    'django.middleware.security.SecurityMiddleware',
    # ...(其他中间件)
]

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技巧

通过增强我们的应用程序的中间件安全性,并采用缓存策略,我们不仅加强了应用程序的外部威胁,还优化了其性能。数据传输的走廊现在更加高效,确保每个信息的传递速度更快、更安全,这是背景中默默运行的机器所实现的,就像翻阅精装书的无缝体验一样。

第9步:使用WhiteNoise配置媒体和静态文件

在我们的Web应用程序的剧院中,媒体和静态文件就像为难忘的表演设置舞台的背景和服装。确保这些元素以高效的方式传递是至关重要的,就像WhiteNoise一样,像一个熟练的舞台经理,确保每个脚本和样式表都以优雅和速度进入。

使用WhiteNoise调整文件的编排:

WhiteNoise是一个实用工具,用于为我们的Django应用程序奏响静态文件的能力,绕过在生产环境中为此目的使用单独的Web服务器的需要。当我们的应用程序的性能至关重要时,这一点尤其方便(我们在第2步中已经做过了,但在这里我将更详细地解释)。

要集成WhiteNoise,我们从简单的安装开始:

pip install whitenoise

接下来,我们更新settings.py,将WhiteNoise引入中间件集合:

# settings.py

MIDDLEWARE = [
    # ...其他中间件类
    'whitenoise.middleware.WhiteNoiseMiddleware'# 将WhiteNoise添加到我们的中间件数组中
    # ...其他中间件类
]

# 配置静态文件设置,集成WhiteNoise以在生产环境中提供静态文件
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')  # 定义收集静态文件的目录
STATICFILES_DIRS = (  # 静态文件的其他位置
    os.path.join(BASE_DIR, 'static'),
)
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'  # WhiteNoise静态文件存储

这个设置使WhiteNoise能够高效地管理静态文件,压缩它们并设置缓存头以优化传递。

为盛大演出做准备:

在我们的应用程序走上舞台之前,我们需要将所有的静态元素聚集在一起,准备好演出。这就是collectstatic命令发挥作用的地方,类似于一次排练,确保每个元素都在正确的位置。

python3 manage.py collectstatic

这个命令提示Django从我们的应用程序和任何第三方应用程序中收集所有静态文件,并将它们放入STATIC_ROOT目录中。然后,WhiteNoise将接管,将这些文件视为其脚本,以进行交付的指挥。

为舞台装扮媒体文件:

虽然静态文件保持不变,但媒体文件是我们戏剧中的动态角色,由用户上传和修改。它们需要仔细处理:

# settings.py

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

这些设置确保用户生成的内容有自己的专用空间,并得到正确的管理。

全球合奏与CDN:

在座无虚席的情况下,内容传递网络(CDN)确保没有观众需要等待。WhiteNoise优雅地将指挥棒交给CDN,确保静态文件不仅被高效地提供,而且在全球范围内进行分发以提高性能:

# settings.py
CDN_URL = 'https://mycdn.example.com'  # 这是CDN服务提供的基本URL
STATIC_URL = CDN_URL + '/static/'  # 这设置了用于提供静态文件的完整URL

通过WhiteNoise和collectstatic的和谐配合,以及CDN在全球范围内分发我们的内容,我们的应用程序已经准备好登上舞台。每个用户请求都能得到迅速的交付,确保体验与精心排练的首演一样流畅和专业。我们的数字幕拉开,演出开始。

第10步:在VPS上进行测试、部署和监控

随着我们接近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应用程序的逐步课程,为了不让这篇文章太长,我将在这里结束。

保护未来:在VPS上部署坚不可摧的Django Web应用程序的逐步指南...

Web服务器的舞台工作人员:Gunicorn:Gunicorn充当我们生产环境的舞台工作人员,是一个可靠的WSGI HTTP服务器,为我们的应用程序注入生命力,使其能够为全球观众表演。配置Gunicorn很简单,但对于一个强大的生产环境来说是必不可少的。

Nginx:伟大的舞台经理:

Nginx是经验丰富的舞台经理,作为反向代理在幕后不知疲倦地工作,管理和引导网络流量的流向,确保每个请求都能顺利到达Gunicorn。与Gunicorn一起,它创建了一个无缝的生产环境。

通过SSL保护掌声:

SSL加密相当于一个安全的剧院,观众和演员之间的每次对话都得到保护。这种加密确保交换的数据保持机密和防篡改。

监控:细心的引座员:

现在应用程序已经交到公众手中,监控工具充当细心的引座员,密切关注表演情况。像Sentry这样的错误跟踪工具或Prometheus这样的监控工具对于确保如果出现任何问题,可以在最小干扰观众的情况下重新设置场景至关重要。

结论:

当我们在10个全面步骤中构建一个安全高效的Django Web应用的旅程即将结束时,我们可以回顾一下所使用的各种工具和技术,这些工具和技术被用来打造这个数字杰作。从基础设置到完善的部署,每一步都是我们Web应用程序的精心编织的细节。

我邀请您为这个创作的勤奋和精湛工艺鼓掌。如果这些细节激发了您的好奇心,或者如果您渴望深入了解Django的世界,我们欢迎您进一步交流和学习。

免责声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

相关文章

探索多种软件架构模式及其实用应用
2024年11月22日19:06
本文深入探讨了多种软件架构模式,包括有界上下文、边车模式、发布-订阅模式、应用网关、微服务、命令职责分离(CQRS)等,介绍了它们的优点、使用场景以及具体应用实例。文章强调根据具体项目需求和团队能力选择最合适的架构,以构建高效和可维护的解决方案,同时展示了各架构模式间的综合应用,提供了丰富的案例和技术细节。
15个高级Python快捷键助您更快编程
2024年11月21日07:02
本文分享了 15 个高级的 Python 编程快捷键,包括上下文管理器、行内字典合并、函数参数解包、链式比较、dataclasses、海象运算符、反转列表、备忘录缓存、splitlines、enumerate、字典推导、zip 用于并行迭代、itertools.chain 扁平化列表、functools.partial 部分函数和 os.path 文件路径管理等,帮助开发者提高编程效率和代码简洁性。
揭示网页开发的 11 个迷思:停止相信这些误区
2024年11月19日22:05
网页开发充满误解,这篇博文针对11个常见迷思进行揭秘。包括网站开发后不需更新、需掌握所有技术、AI会取代开发者等。强调持续学习、专业化、用户体验的重要性,澄清误区如多任务处理的必要性和最新技术的必需性。文章提醒开发者注重实用而非追求完美代码,以务实态度面对开发工作。
你知道 CSS 的四种 Focus 样式吗?
2024年11月18日21:41
本文介绍了四种 CSS focus 样式::focus、:focus-visible、:focus-within 以及自定义的 :focus-visible-within,帮助提升网站用户体验。:focus 样式应用于被选中元素;:focus-visible 仅在键盘导航时显示;:focus-within 用于父元素;自定义 :focus-visible-within 结合两者效果。合理运用这些样式能使网站更方便键盘用户导航。
利用 Python 实现自动化图像裁剪:简单高效的工作流程
2024年11月11日20:49
使用 Python 和 OpenCV 自动裁剪图像,轻松实现 16:9 的完美构图。这个指南介绍了如何通过代码进行灰度化、模糊处理和边缘检测,最终识别出最重要的部分进行裁剪。特别适合需要批量处理图像的情况,节省大量时间。
每位资深前端开发人员都应了解的 TypeScript 高级概念
2024年11月11日02:07
资深前端开发者应了解 TypeScript 的高级概念,如联合类型、交叉类型、类型保护、条件类型、映射类型、模板字面量类型和递归类型。这些特性可提升代码的可维护性和可扩展性,确保在开发复杂应用时实现更高的类型安全性和效率。