Руководство часть 7: Сессии

此部分通过添加主页会话的会话计数器来扩展LocalLibrary网站. 这是一个相对简单的示例,但是它演示了如何使用会话分析来分析站点上匿名用户的行为.

Требования: 完成所有先前部分的学习,包括Django Guide.第6部分:广义列表显示和详细信息
Цель: 了解如何申请会议.

Обзор

在前面的部分中,我们创建了LocalLibrary网站,该网站允许用户从目录中检索书籍和作者的列表. 目前,该站点的每个访问者都可以访问从数据库动态生成的相同页面和信息类型.

在"真实"库中,您希望向用户提供各个服务,具体取决于他的偏好和使用该站点的先前经验,他的设置等. 例如,下次访问该站点时,您可以为已经收到错误消息的用户隐藏错误消息,或者保存并考虑用户设置(例如,由于某些搜索而在页面上显示的数据量).

会话允许您实现这种功能,该功能允许您存储和接收基于站点上单个用户行为获得的任意数据.

Что такое сессии?

浏览器和服务器之间的所有交互都是使用HTTP协议执行的,该协议不会保留其状态( 无状态) . 这一事实意味着客户端和服务器之间的消息是完全彼此独立的-也就是说,没有依赖于先前消息的"序列"或行为的表示. 因此,如果要创建一个网站来跟踪与客户端(浏览器)的交互,则需要自己实现.

Сессии являются механизмом, который использует Django (да и весь остальной "Интернет") для отслеживания "состояния" между сайтом и каким-либо браузером. Сессии позволяют вам хранить произвольные данные браузера и получать их в тот момент, когда между данным браузером и сайтом устанавливается соединение. Данные получаются и сохраняются в сессии при помощи соответствующего "ключа".

Django使用Cookie,其中包含一个特殊的会话标识符 ,该标识符可在其余的,每个浏览器和相应的会话之间进行标识. 默认情况下,真实会话数据存储在站点数据库中(这比将数据存储在cookie中更安全,因为cookie可能容易受到网络罪犯的攻击). 但是,您可以选择将Django配置为将会话数据保存在其他位置(缓存,文件,"安全" cookie). 但是,默认存储仍然是一个安全的好选择.

Подключение сессий

当我们创建网站的骨架时,会话自动变为可用(在手册的第二部分).

在项目文件的INSTALLED_APPSMIDDLEWARElocallibrary / locallibrary / settings.py )中执行必要的配置,如下所示:

INSTALLED_APPS = [
    ...
    'django.contrib.sessions',
    ....

MIDDLEWARE = [
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    ....

Применение сессий

您可以通过request参数访问相应映射中的session变量( HttpRequest作为第一个参数传递给每个映射). 会话变量是与特定用户的连接(或更准确地说,是与特定浏览器的连接,该连接使用从浏览器cookie中获取的会话标识符(id)确定).

变量(或字段) session是一个字典对象,用于读取和写入无数次. 使用它,您可以执行任何标准操作,包括清除所有数据,检查密钥,数据周期等等. 大多数时候,您将花费在普通的"字典"操作上-获取和设置值.

下面的代码片段向您展示了如何使用与当前会话(浏览器)相关的键" my_car "来接收,设置和删除一些数据.

注意 :Django的最大优点之一是,您无需考虑将会话连接到显示中的当前请求的机制. 在下面的代码段中,您需要知道的是my_car已连接到发送当前请求的浏览器.

# Получение значения сессии при помощи ключа(то есть, 'my_car'). 
# Если такого ключа нет, то возникнет ошибка KeyError
my_car = request.session['my_car']

# Получение значения сессии. Если значения не существует,
# то вернется значение по умолчанию ('mini')
my_car = request.session.get('my_car', 'mini')

# Передача значения в сессию
request.session['my_car'] = 'mini'

# Удаление значения из сессии
del request.session['my_car']

此API具有其他方法,这些方法主要用于管理与会话关联的cookie. 例如,有一些方法可以验证客户端浏览器是否支持Cookie,也可以使用其他方法来设置和检查Cookie的期限,以及清除商店中过期的会话. 您可以在如何使用会话 (Django文档)部分中找到该API的详细说明.

Хранение данных сессии

默认情况下,Django将会话数据保存到数据库,并仅在更改删除会话后才将适当的cookie发送到客户端. 如果您使用会话密钥更新任何数据(如上一片段所示),则不必担心保存过程! 例如:

# Данное присваивание распознается как обновление сессии 
# и данные будут сохранены
request.session['my_car'] = 'mini'

如果更新会话数据的信息,然后Django将无法识别这些更改并不会自动保存数据(例如,如果你改变了" wheels "变量"里面my_car ",如下图所示). 在这种情况下,您需要明确指出会话已更改.

# Объект сессии модифицируется неявно. 
# Изменения НЕ БУДУТ сохранены!
request.session['my_car']['wheels'] = 'alloy'

# Явное указание, что данные изменены. 
# Сессия будет сохранена, куки обновлены (если необходимо).
request.session.modified = True

注意 :您可以通过在项目设置文件( locallibrary / locallibrary / settings.py )中设置SESSION_SAVE_EVERY_REQUEST = True来更改会话的行为,以使它们记录数据库中的所有更改并发送Cookie,并根据每个请求发送cookie.

Простой пример — получение числа визитов

作为现实中的一个例子,我们将以如下方式更新我们的图书馆,以告知用户他对LocalLibrary网站主页的访问次数.

打开/locallibrary/catalog/views.py并在下面以黑体添加更改.

def index(request):
    ...

    num_authors=Author.objects.count()  # The 'all()' is implied by default.
    
    # Number of visits to this view, as counted in the session variable.
    num_visits=request.session.get('num_visits', 0)
    request.session['num_visits'] = num_visits+1
    
    # Render the HTML template index.html with the data in the context variable.
    return render(
        request,
        'index.html',
        context={'num_books':num_books,'num_instances':num_instances,'num_instances_available':num_instances_available,'num_authors':num_authors,
            'num_visits':num_visits}, # num_visits appended
    )

首先,我们从会话中获取'num_visits'的值,如果之前未设置,则返回0. 每次收到请求时,我们都会将该值增加一并将其保存回会话中(直到下一个用户访问此页面). 然后,变量num_visits通过上下文变量context传递到模板.

注意 :您可以检查浏览器对cookie的支持(例如,请参阅如何使用session ),或以一种无关紧要的方式设计UI.

要显示变量的值,请在以下片段中,将代码的底行添加到网站主页( /locallibrary/catalog/templates/index.html )的下部"动态内容"中的模板中:

<h2>Dynamic content</h2>

<p>The library has the following record counts:</p>
<ul>
<li><strong>Books:</strong> {{ num_books }}</li>
<li><strong>Copies:</strong> {{ num_instances }}</li>
<li><strong>Copies available:</strong> {{ num_instances_available }}</li>
<li><strong>Authors:</strong> {{ num_authors }}</li>
</ul>

<p>You have visited this page {{ num_visits }}{% if num_visits == 1 %} time{% else %} times{% endif %}.</p>

保存更改并重新启动服务器. 每当刷新页面时,此值都应更改.

Итоги

您学习了如何使用会话来改善与匿名用户的交互.

在下一篇文章中,我们将介绍身份验证和授权框架(权限),并向您展示如何支持用户帐户.

Смотрите также