【问题标题】:The session variable is lost, in Django会话变量丢失,在 Django
【发布时间】:2020-01-09 10:07:11
【问题描述】:

在应该是多公司的系统中,我使用 context_processors.py 通过从侧边栏中进行选择来加载公司选项。用户可以随时更换公司。

当用户选择一家公司时,该选项被记录在一个会话变量中。

发生在用户换页时,session变量的信息丢失了。

我做错了什么或没有做什么?有没有更好的方法来做到这一点?

相关代码sn-ps如下:

context_processors.py

from apps.client.models import Client

def units (request):
    # Dictionary with business options
    clients = Client.objects.values ​​(
        "client_id",
        "company_id__name",
    )
    clients_list = []
    for client in clients:
        clients_list.append (
            {
                'client_id': client ['client_id'],
                'name': client ['company_id__name']
            }
        )
    return {'clients_list': clients_list}

base.html

# System base page.
# Displays the list of business options.
<select class = "form-control select2">
<option value = "{{request.session.unit_id}}"> {{request.session.unit_id}} </option>
{% for client in clients_list%}
<option value = "{{client.client_id}}"
{% if request.session.unit_id == client.client_id%}
selected
{% endif%}>
{{client.client_id}}
</option>
{% endfor%}
</select>
...

# Whenever a company is selected ...
<script>
$ ("# select_unit"). click (function () {
    var option_id = $ (this) .val ();
    var url = "{% url 'home: set_unit'%}";
    $ .ajax ({
        type: "GET",
        url: url,
        data: {'unit_id': option_id},
        success: function () {}
    });
});
</script>

view.py

# View that registers the variable in the session.
def set_unit (request):
    unit_id = request.GET.get ("unit_id")
    request.session ['unit_id'] = unit_id

settings.py

MIDDLEWARE = [
    'apps.core.middleware.AppMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django_globals.middleware.Global',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(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',
                'apps.home.context_processors.units',
            ],
        },
    }
]

【问题讨论】:

  • 您的set_unit 视图没有返回任何内容?我认为这可能是个问题。怎么称呼?
  • 设置单元总是正确地提供会话。事实证明,在切换页面时,会话不再显示用户选择的值
  • 我不明白。视图总是必须返回一个 HttpResponse。你的没有。
  • set_unit 视图只获取所选公司和会话变量上的箭头。页面不应该被重定向,它应该留在原处。请记住,公司选择的选择是一个侧边栏组件,因此不应该有页面重定向。而问题正是出现在这个事实中:在选择了公司之后,用户访问了系统的任何页面——此时定义的会话变量丢失了。
  • 我想也许我没有正确设置会话变量,也许它遗漏了一些细节。

标签: python django session


【解决方案1】:

我认为问题是你没有设置会话被修改,在更改会话值之后。

request.session.modified = True

另一个选项是在你的 settings.py 中添加:

SESSION_SAVE_EVERY_REQUEST=True

【讨论】:

  • 如果您只是更改一个简单的键值对,则不需要设置会话被修改,Django 会自动检测这些更改。 docs here
  • 我不知道。谢谢!
【解决方案2】:

设置会话变量的视图需要返回响应。由于您使用 Ajax 调用它,因此带有简单的 {'status': 'ok'} 字典的 JsonResponse 就可以了。在set_unit末尾添加这一行:

return JsonResponse({'status': 'ok'})

如果您查看浏览器开发工具网络选项卡或控制台,您会看到当前您的请求正在生成错误,因为视图不应返回 None。这就是没有保存会话并且没有保持会话变量的新状态的原因。

【讨论】:

    猜你喜欢
    • 2011-04-15
    • 2011-12-05
    • 2011-03-09
    • 2012-10-18
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多