第二章:进阶 Django
注意,第一章是开发基础,第二章是高级开发必备,第三章是项目实战,如果要进行第三章实战开发,必须熟练掌握第一章第二章,如有问题自行百度
2.1 Django 身份验证
- Django 用户认证
- Django 身份验证框架
Django 身份验证
在 Web 应用程序中,用户认证是一个重要的功能,用于验证用户的身份并授权其访问受限资源。Django 提供了内置的用户认证系统,使得用户认证变得简单和高效。
以下是关于 Django 身份验证的详细介绍:
-
Django 用户认证: Django 提供了内置的用户模型(User Model),可以轻松地处理用户认证。在 Django 的认证系统中,用户认证是基于用户名和密码的。用户可以使用用户名和密码进行注册、登录和注销等操作。Django 的用户模型提供了一些常用的字段和方法,例如用户名、密码散列存储、验证凭证等。
a. 用户注册: 用户可以通过创建新的用户对象来进行注册。可以使用
User.objects.create_user()
或User.objects.create_superuser()
方法来创建普通用户和超级用户(拥有特权和管理功能)。以下是一个示例:from django.contrib.auth.models import User # 创建普通用户 user = User.objects.create_user(username='john', password='secret') # 创建超级用户 superuser = User.objects.create_superuser(username='admin', password='admin', email='admin@example.com')
b. 用户登录: 用户可以使用用户名和密码进行登录。Django 提供了
authenticate()
和login()
函数来验证用户凭证并创建登录会话。以下是一个示例:from django.contrib.auth import authenticate, login def login_view(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) # 用户验证成功,执行跳转或其他操作 # ... else: # 用户验证失败,显示错误消息 # ... else: # 显示登录表单 # ...
c. 用户注销: 用户可以通过调用
logout()
函数来注销当前登录的用户会话。以下是一个示例:from django.contrib.auth import logout def logout_view(request): logout(request) # 执行跳转或其他操作 # ...
-
Django 身份验证框架是 Django 提供的一套用于处理用户认证的功能和工具集合。它简化了用户认证的实现,并提供了一些内置的视图、模板标签和上下文处理器,以及其他相关的功能。下面详细介绍 Django 身份验证框架的主要组件,并附上示例代码。
-
登录视图(LoginView): Django 提供了内置的登录视图
django.contrib.auth.views.LoginView
,它处理用户登录的逻辑。你可以在 URLConf 中指定该视图,并通过自定义模板来呈现登录表单。以下是一个示例:# urls.py from django.urls import path from django.contrib.auth.views import LoginView urlpatterns = [ path('login/', LoginView.as_view(template_name='login.html'), name='login'), ]
<!-- login.html --> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">登录</button> </form>
上述示例中,我们指定了
LoginView
视图,并指定了自定义的模板login.html
,用于呈现登录表单。在模板中,使用{{ form.as_p }}
渲染表单字段。 -
注销视图(LogoutView): Django 提供了内置的注销视图
django.contrib.auth.views.LogoutView
,它处理用户注销的逻辑。你可以在 URLConf 中指定该视图,并通过自定义模板来呈现注销成功的页面。以下是一个示例:# urls.py from django.urls import path from django.contrib.auth.views import LogoutView urlpatterns = [ path('logout/', LogoutView.as_view(template_name='logout.html'), name='logout'), ]
<!-- logout.html --> <h3>注销成功!</h3>
上述示例中,我们指定了
LogoutView
视图,并指定了自定义的模板logout.html
,用于呈现注销成功的页面。 -
认证上下文处理器: Django 提供了一个认证上下文处理器
django.contrib.auth.context_processors.auth
,它将当前登录的用户对象添加到模板上下文中。这样,在模板中就可以直接访问用户对象,以便根据用户的认证状态进行条件渲染。以下是一个示例:# settings.py ... TEMPLATES = [ { ... 'OPTIONS': { 'context_processors': [ ... 'django.contrib.auth.context_processors.auth', ... ], }, }, ] ...
在上述示例中,我们将
django.contrib.auth.context_processors.auth
添加到模板引擎的上下文处理器列表中。<!-- template.html --> {% if user.is_authenticated %} <p>欢迎,{{ user.username }}!</p> <a href="{% url 'logout' %}">注销</
-
登录验证装饰器: Django 提供了一个装饰器
@login_required
,用于装饰需要用户登录才能访问的视图函数。如果用户未登录,则会重定向到登录页面。这可以确保只有经过身份验证的用户才能访问特定的页面或执行特定的操作。以下是一个示例:
from django.contrib.auth.decorators import login_required from django.shortcuts import render @login_required def my_view(request): # 只有登录用户才能访问该视图函数 return render(request, 'my_view.html')
在上述示例中,我们使用
@login_required
装饰器将my_view
视图函数装饰起来,以确保只有登录用户才能访问该视图函数。- 自定义用户认证: Django 还允许你自定义用户认证方式,例如使用电子邮件而不是用户名作为登录凭据。你可以继承 Django 的
AbstractBaseUser
类来创建自定义用户模型,并实现相应的用户认证逻辑。以下是一个示例:
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager from django.db import models class MyUserManager(BaseUserManager): def create_user(self, email, password=None, **extra_fields): if not email: raise ValueError('The Email field must be set') email = self.normalize_email(email) user = self.model(email=email, **extra_fields) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, password=None, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) return self.create_user(email, password, **extra_fields) class MyUser(AbstractBaseUser): email = models.EmailField(unique=True) # 其他自定义字段 objects = MyUserManager() USERNAME_FIELD = 'email' def __str__(self): return self.email
在上述示例中,我们定义了
MyUserManager
和MyUser
类来实现自定义用户认证逻辑。MyUser
继承了AbstractBaseUser
类,并指定email
字段作为登录凭据。MyUserManager
定义了创建用户和创建超级用户的方法。通过使用 Django 身份验证框架的组件,你可以轻松地实现用户认证和访问控制功能。这些组件提供了一系列的工具和功能,帮助你处理用户注册、登录、注销以及对受限资源的访问控制。你还可以根据需要自定义用户认证逻辑,以适应特定的业务需求。
-
2.2 Django 高级数据库操作
- Django 数据库查询
- Django 模型关系
- Django 数据库迁移
2.2 Django 高级数据库操作
Django 提供了强大的数据库操作功能,使得与数据库的交互变得简单和高效。在本节中,将详细介绍以下 Django 高级数据库操作的内容:
-
Django 数据库查询: Django 使用对象关系映射(Object-Relational Mapping,ORM)的方式来进行数据库查询。ORM 允许你通过使用 Python 代码来执行数据库操作,而无需直接编写 SQL 查询语句。Django 提供了丰富的查询 API,包括过滤查询、排序、聚合、连接等功能,以便灵活地操作数据库。
a. 过滤查询: 可以使用
filter()
方法来进行过滤查询,根据指定的条件筛选出符合要求的数据库记录。以下是一个示例:from myapp.models import Book # 查询价格小于 50 的图书 books = Book.objects.filter(price__lt=50)
b. 排序: 可以使用
order_by()
方法对查询结果进行排序,根据指定的字段进行升序或降序排序。以下是一个示例:from myapp.models import Book # 按照价格降序排序 books = Book.objects.order_by('-price')
c. 聚合: 可以使用
aggregate()
方法对查询结果进行聚合操作,例如计算总数、平均值、最大值等。以下是一个示例:from myapp.models import Book from django.db.models import Sum # 计算所有图书的总价格 total_price = Book.objects.aggregate(total_price=Sum('price'))
d. 连接: Django 的 ORM 支持在查询中进行连接操作,以获取相关联的对象。例如,可以使用
select_related()
方法进行前向关联查询,或使用prefetch_related()
方法进行反向关联查询。以下是一个示例:from myapp.models import Author # 获取所有作者及其关联的图书 authors = Author.objects.select_related('book_set')
-
Django 模型关系: 在 Django 中,模型之间可以建立各种类型的关系,包括一对一关系、一对多关系和多对多关系。这些关系在数据库中以外键和中间表的形式进行映射。
a. 一对一关系: 一对一关系表示两个模型之间的唯一关联。例如,一个人只能有一个身份证号码。在 Django 中,可以通过在模型字段中使用
OneToOneField
来定义一对一关系。以下是一个示例:from django.db import models class Person(models.Model): name = models.CharField(max_length=100) class IDCard(models.Model): number = models.CharField(max_length=20) person = models.OneToOneField(Person, on_delete=models.CASCADE)
b. 一对多关系: 一对多关系表示一个模型的实例可以与多个另一个模型的实例相关联。例如,一个作者可以写多本书。在 Django 中,可以通过在模型字段中使用
ForeignKey
来定义一对多关系。以下是一个示例:from django.db import models class Author(models.Model): name = models.CharField(max_length=100) class Book(models.Model): title = models.CharField(max_length=100) author = models.ForeignKey(Author, on_delete=models.CASCADE)
c. 多对多关系: 多对多关系表示两个模型的实例之间存在多对多的关联。例如,一个学生可以选择多个课程,一个课程也可以有多个学生。在 Django 中,可以通过在模型字段中使用
ManyToManyField
来定义多对多关系。以下是一个示例:from django.db import models class Student(models.Model): name = models.CharField(max_length=100) courses = models.ManyToManyField('Course') class Course(models.Model): name = models.CharField(max_length=100)
-
Django 数据库迁移: 数据库迁移是 Django 提供的一种机制,用于管理数据库结构的变化。通过数据库迁移,你可以轻松地创建、修改或删除数据库表、字段和索引等。Django 使用
makemigrations
和migrate
命令来生成和应用数据库迁移。a. 生成迁移文件: 使用
makemigrations
命令可以生成数据库迁移文件,该文件包含了你对模型的更改操作。以下是一个示例:$ python manage.py makemigrations myapp
b. 应用迁移文件: 使用
migrate
命令可以应用数据库迁移文件,将数据库结构更新到最新状态。以下是一个示例:$ python manage.py migrate
通过生成和应用数据库迁移,你可以方便地管理数据库结构的变化,而无需手动编写 SQL 脚本来执行数据库操作。
以上是 Django 的高级数据库操作的主要内容。通过使用 Django 的查询 API 和模型关系,以及数据库迁移功能,你可以更灵活地与数据库进行交互,并轻松地管理数据库结构的变化。这些功能有助于开发高效、可维护的 Django 应用程序。
2.3 Django 缓存
- Django 缓存介绍
- Django 缓存配置
- Django 缓存实例
Django 提供了缓存框架,用于存储和检索数据的快速访问副本。缓存可以显著提高网站的性能,减少对数据库或其他外部资源的频繁访问。在本节中,将详细介绍以下 Django 缓存的内容:
-
Django 缓存介绍: Django 缓存框架允许你将计算结果、数据库查询结果、视图函数的输出或其他重复访问的数据存储在缓存中。当下次需要相同的数据时,可以直接从缓存中获取,而无需重新计算或查询。这可以大大提高响应时间和整体性能。
-
Django 缓存配置: 在 Django 中配置缓存需要在
settings.py
文件中进行设置。主要涉及以下几个配置项:a.
CACHES
设置:CACHES
配置项用于指定缓存的后端和相关的参数。Django 支持多种缓存后端,如内存缓存、文件缓存、数据库缓存等。以下是一个示例配置:CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '127.0.0.1:11211', } }
在上述示例中,我们配置了默认的缓存后端为 Memcached,并指定了 Memcached 的地址和端口。
b.
CACHE_MIDDLEWARE_ALIAS
和CACHE_MIDDLEWARE_SECONDS
设置: 这两个配置项用于在中间件层级应用缓存。CACHE_MIDDLEWARE_ALIAS
指定了要使用的缓存后端,CACHE_MIDDLEWARE_SECONDS
指定了缓存的有效期。以下是一个示例配置:pythonCopy codeCACHE_MIDDLEWARE_ALIAS = 'default' CACHE_MIDDLEWARE_SECONDS = 60
在上述示例中,我们将缓存后端设置为默认缓存后端,缓存有效期为 60 秒。
-
Django 缓存实例: 使用 Django 缓存框架非常简单。你可以在视图函数、模型方法或任何需要缓存的地方使用
cache
装饰器或函数来缓存数据。以下是一个示例:from django.core.cache import cache def get_books(): books = cache.get('books') if books is None: # 缓存中不存在数据,执行查询并存储到缓存中 books = Book.objects.all() cache.set('books', books, 60) # 存储 60 秒 return books
在上述示例中,我们首先尝试从缓存中获取书籍数据,如果缓存中不存在,则执行数据库查询并将结果存储到缓存中。我们使用
cache.get()
方法获取缓存数据,使用cache.set()
方法将
数据存储到缓存中,并设置缓存的有效期为 60 秒。
除了装饰器和函数,Django 还提供了缓存 API,用于更灵活地操作缓存,如读取、写入、删除缓存等操作。
通过合理地使用缓存,可以显著提高 Django 应用程序的性能和响应速度。你可以根据具体的需求选择合适的缓存后端,并在适当的地方使用缓存装饰器或函数来缓存数据。记得根据数据的更新频率设置合适的缓存过期时间,以确保数据的及时更新。
2.4 Django 安全
- Django 安全简介
- Django 安全设置
- Django 安全实践
Django 是一个注重安全性的 Web 框架,提供了多种安全功能和机制,以保护应用程序免受常见的 Web 安全威胁。在本节中,将详细介绍以下 Django 安全的内容:
-
Django 安全简介: Django 提供了一系列的安全功能,包括跨站点请求伪造(CSRF)防护、跨站脚本攻击(XSS)防护、点击劫持防护、SQL 注入防护等。这些功能都是默认开启的,并且遵循最佳实践来保护应用程序的安全性。
-
Django 安全设置: Django 的安全设置位于
settings.py
文件中,你可以根据需要进行相应的配置。以下是一些常见的 Django 安全设置:a.
SECRET_KEY
:SECRET_KEY
是一个用于加密和验证会话数据、密码哈希等敏感信息的密钥。确保将其设置为一个随机且复杂的字符串,并将其保存在安全的地方。示例配置如下:SECRET_KEY = 'your_secret_key'
b.
DEBUG
: 在生产环境中,将DEBUG
设置为False
,以禁用详细的错误信息和调试功能。示例配置如下:DEBUG = False
c.
CSRF_COOKIE_SECURE
和SESSION_COOKIE_SECURE
: 将这两个配置项设置为True
,以确保 CSRF 令牌和会话 cookie 只能通过 HTTPS 进行传输。示例配置如下:CSRF_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True
-
Django 安全实践: 在开发 Django 应用程序时,还应遵循一些安全实践,以增加应用程序的安全性。以下是一些常见的安全实践:
a. 输入验证和过滤: 始终对用户输入进行验证和过滤,以防止恶意输入导致的安全漏洞,如 SQL 注入、跨站脚本攻击等。使用 Django 提供的表单验证和模型验证来确保输入数据的合法性。
b. 密码安全: 在存储用户密码时,应使用适当的密码哈希算法,如 PBKDF2、bcrypt 或 Argon2,以确保密码的安全性。Django 提供了内置的密码哈希功能,可以轻松实现密码的安全存储。
c. 权限和访问控制: 使用 Django 的权限系统来管理用户的访问权限,并确保只有授权用户可以访问敏感数据和功能。使用装饰器或中间件来限制非授权用户的访问。
d.
定期更新和升级: 定期更新 Django 版本和相关的库,以获取最新的安全补丁和功能改进。及时升级应用程序的依赖项,以避免已知的安全漏洞。
以上是 Django 安全的主要内容。通过配置安全设置和遵循安全实践,可以确保 Django 应用程序的安全性,并保护应用程序免受常见的 Web 安全威胁。