Django 1.11.3无Request批量操作Session及预配置技术问询
Hey there, let's break down your two Django Session questions specifically for your setup (Django 1.11.3 + Python 3.5):
问题1:无Request时通过用户ID/手机号访问并修改Session
Django stores session data in the django_session database table, and you can directly interact with the Session model to access sessions without a request object. Here's how to do it:
Step 1: Retrieve sessions linked to a user ID
By default, Django stores the authenticated user's ID in the session under the key _auth_user_id. We'll need to deserialize the stored session data (since it's pickled by default in Django 1.11) to check this value:
from django.contrib.sessions.models import Session from django.contrib.sessions.serializers import PickleSerializer from django.utils import timezone def get_user_sessions(user_id): # Filter only active (non-expired) sessions active_sessions = Session.objects.filter(expire_date__gt=timezone.now()) serializer = PickleSerializer() user_sessions = [] for session in active_sessions: try: # Deserialize the session data session_data = serializer.loads(session.session_data) # Check if this session belongs to the target user if session_data.get('_auth_user_id') == str(user_id): user_sessions.append((session, session_data)) except Exception: # Skip corrupted/invalid sessions continue return user_sessions
Step 2: Modify sessions to add your list field
Once you have the user's sessions, you can add the new field and save the updated session data:
# Example: Get sessions for user with ID 123 user_sessions = get_user_sessions(123) serializer = PickleSerializer() for session, data in user_sessions: # Add the new list field (initialize as empty if not exists) data.setdefault('my_custom_list', []) # Optional: Populate the list with initial values # data['my_custom_list'] = ['item1', 'item2'] # Serialize the updated data and save the session session.session_data = serializer.dumps(data) session.save()
Step 3: Access via phone number
If you need to target users by phone number, first fetch the user object using the phone field, then use their ID to find sessions:
from django.contrib.auth.models import User # Or your custom user model # Replace with your user model's phone field lookup target_user = User.objects.get(phone='1234567890') user_sessions = get_user_sessions(target_user.id) # Proceed to modify sessions as above
问题2:在Request发起前设置Session的格式
If you want to ensure sessions have a consistent structure (like your new list field) from the moment they're created, here are two reliable approaches for Django 1.11:
Option 1: Custom Session Initialization Middleware
Create a middleware that runs after Django's SessionMiddleware to set default values when a session is first created:
# myapp/middleware.py from django.utils.deprecation import MiddlewareMixin class SessionStructureMiddleware(MiddlewareMixin): def process_request(self, request): # Check if the session is new or missing our custom field if not request.session.get('my_custom_list'): # Initialize the list field as empty request.session['my_custom_list'] = []
Then add this middleware to your settings.py after Django's SessionMiddleware:
# settings.py MIDDLEWARE = [ # ... other middleware ... 'django.contrib.sessions.middleware.SessionMiddleware', 'myapp.middleware.SessionStructureMiddleware', # Add your middleware here # ... other middleware ... ]
Option 2: Use the User Login Signal
If you only need to set the session structure when a user logs in, hook into Django's user_logged_in signal:
# myapp/signals.py from django.contrib.auth.signals import user_logged_in from django.dispatch import receiver @receiver(user_logged_in) def init_session_on_login(sender, request, user, **kwargs): # Set default list field if it doesn't exist if 'my_custom_list' not in request.session: request.session['my_custom_list'] = []
Don't forget to register the signals in your app's apps.py:
# myapp/apps.py from django.apps import AppConfig class MyAppConfig(AppConfig): name = 'myapp' def ready(self): import myapp.signals
And update settings.py to use your custom AppConfig:
# settings.py INSTALLED_APPS = [ # ... 'myapp.apps.MyAppConfig', # Replace 'myapp' with your app name # ... ]
内容的提问来源于stack exchange,提问作者zephyr.mao

