如何在 Django 会话模型中设置自定义字段?
Posted
技术标签:
【中文标题】如何在 Django 会话模型中设置自定义字段?【英文标题】:How to set a custom field in a Django session model? 【发布时间】:2017-06-15 23:33:33 【问题描述】:我已经根据this 延长了 Django 中的会话。总之,我添加了一个名为account_id
的字段来保存会话所属用户的用户ID。
一切正常,除了我添加的自定义字段account_id
没有在登录时设置。这样做:
from django.contrib import auth
from MyApp.models import CustomSession
def login(request):
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
try:
auth.login(request, user)
session_key = request.session.session_key
# CODE HERE
if session_key is not None:
return HttpResponse(json.dumps('status': 'Success'))
else:
return HttpResponse(json.dumps('status': 'Fail'))
我已尝试将以下内容发送到CODE HERE
。但是,它们都不起作用:
request.session.model.account_id = user.id
session = CustomSession.objects.get(pk=session_key)
session.account_id = user.id
session.modified = True
request.session.account_id = user.id
request.session[account_id] = user.id
在每次尝试中,account_id
在数据库中都是NULL
。
我在这里错过了什么?
【问题讨论】:
您想这样做的原因是什么?在大约 99.9% 的情况下,不需要以这种方式将会话与用户联系起来。 @trixn 我正在尝试轻松获取在线用户列表。 这将如何帮助您做到这一点? @DanielRoseman 我在用户断开连接时注销用户(用户使用 WebSockets 连接,所以我可以判断他们是否连接)。因此,在任何给定时间,会话表都会告诉我在线用户列表。 我不知道在扩展 Django 的 Session 类之后我必须将代码放在哪里。文档包含代码,但不包含要放置的位置。任何人都可以指导向数据库添加其他字段吗? 【参考方案1】:您错过了 CustomSession 是一个模型的事实;您需要保存实例,而不是像在版本 2 中那样对其设置“修改”。
session = CustomSession.objects.get(pk=session_key)
session.account_id = user.id
session.save()
【讨论】:
不走运。这也不起作用。account_id
仍然是 NULL
。
我的猜测是 Django 在退出 login
方法时会以某种方式重新保存会话,但是省略了 account_id
。【参考方案2】:
如果您想在会话表中提供自定义名称或创建自定义字段,您可以按照以下步骤操作。
定义自定义会话后端:
my_project
my_project/
settings.py
session_backend.py
...
user/
models.py
...
from django.contrib.sessions.backends.db import SessionStore as DBStore
import user
class SessionStore(DBStore):
@classmethod
def get_model_class(cls):
return user.models.MySession
def create_model_instance(self, data):
"""
overriding the function to save the changes to db using `session["user_id"] = user.id` .
This will create the model instance with the custom field values.
When you add more field to the custom session model you have to update the function
to handle those fields as well.
"""
obj = super().create_model_instance(data)
try:
user_id = data.get('user_id')
except (ValueError, TypeError):
user_id = None
obj.user_id = user_id
return obj
然后在settings.py
中导入您的自定义类
SESSION_ENGINE = "my_project.session_backend"
在应用程序的models.py
中定义自定义模型,例如user
from django.contrib.sessions.models import Session
class MySession(Session):
# you can also add custom field if required like this user column which can be the FK to the user table
user = models.ForeignKey('user', on_delete=models.CASCADE)
class Meta:
app_label = "user"
db_table = "my_session"
现在运行以下命令进行迁移
python manage.py makemigrations
python manage.py migrate
完成:)
【讨论】:
谢谢,这行得通,但由于递归导入,我还必须将会话模型放在 session_backend.py 中以上是关于如何在 Django 会话模型中设置自定义字段?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 django 模板中设置自定义 forloop 起点
如何在使用集合处理器在摄取节点管道中设置自定义索引时解析字段