我想使用我的Django应用程序作为基于会话的在线服务的中继,并在所有用户之间共享此会话。为此,我配置了一个python-requests Session对象。
我想在Django启动时初始化这个会话,并使它永远活跃。我的想法是,通过允许特定请求的视图访问会话对象,让所有对Django应用程序的请求共享会话对象。
在<<p> strong>瓶设置(用于实验目的)相当容易:from flask import Flask, render_template, request, session
from requests import Session
app = Flask(__name__)
session = Session()
session.post() # Setup Session by logging in
@app.route("/")
def use_session():
reply = session.get() # Get resource from web service
return jsonify(reply)
这里session
将在启动时创建,并且可以被use_session()
访问。
我努力在Django中设置相同的。创建会话的首选位置是哪里?
在Django中,你的Flask代码相当于将相同的逻辑放在views.py
文件中:
# yourapp/views.py
from django.http import HttpResponse
from requests import Session
session = Session()
session.post('https://httpbin.org/post') # Setup Session by logging in
def use_session(request):
reply = session.get('https://example.com') # Get resource from web service
return HttpResponse(reply.content, status=reply.status_code)
# yourproject/urls.py
from django.urls import path
from yourapp.views import use_session
urlpatterns = [
path('', use_session)
]
该对象将在您启动服务器时创建。
这种方法的一个问题是,在现实世界的部署中,为了避免线程阻塞,你通常会运行多个应用程序副本(不管它是Flask还是Django或任何其他框架),在同一服务器上使用多个CPU内核或有多个服务器,每个副本最终都会有自己的会话,这可能工作得很好,但可能会有问题。
在这种情况下,您可以通过使用pickle模块序列化Python对象1并将字节数据存储在数据库中来跨多个进程共享该对象。一个存放数据的好地方是Redis或Memcached,但Django的ORM也可以使用:
# yourapp/models.py
from django.db import models
class Session(models.Model):
pickled = models.BinaryField()
# yourapp/views.py
import pickle
from django.http import HttpResponse
from requests import Session
from . import models
def use_session(request):
# Load the pickled session from the database
session_db_obj = models.Session.objects.first()
if session_db_obj:
# Un-pickle the session
session = pickle.loads(session_db_obj.pickled)
else:
# Create a new session
session = Session()
session.post('https://httpbin.org/post') # Setup Session by logging in
# Create the database object, pickle the session and save it
session_db_obj = models.Session()
session_db_obj.pickled = pickle.dumps(session)
session_db_obj.save()
reply = session.get('https://example.com') # Get resource from web service
return HttpResponse(reply.content, status=reply.status_code)
1:不是任何对象都可以可靠地pickle和unpickle,要小心!
设置它的最佳位置可能是在settings.py
中,因为它在应用程序初始化之前被调用,您可以轻松地从那里导入代码。
也就是说,您可能想要查看连接池或在会话顶部有一个包装器,以便在失败时重新创建它。网络并不像看起来那么可靠,如果你计划让会话长时间运行,它会增加会话在某个时刻被停止的机会。