如何在Django的forms.py中获取运行时request.session的值?
解决Django表单动态过滤QuerySet的验证错误问题
我来帮你梳理下问题所在,然后给出可行的解决方案:
1. 表单字段定义位置错误
你在__init__方法里重新定义了name和referenced_catalog字段,这会打乱Django的表单验证流程——表单字段应该定义在类级别,而非初始化方法内部。正确的做法是先在类里声明字段,再在__init__中修改referenced_catalog的queryset。
2. Meta类未包含所需字段
你的Meta类中fields只指定了('name',),但表单实际还有referenced_catalog字段,这会导致该字段不被表单识别,进而引发验证或渲染异常。
3. SessionStore使用错误
你新建了一个空的SessionStore实例,自然找不到user_context_id。应该直接使用当前请求的request.session来获取会话数据,就像你最初尝试的那样。
修正后的完整代码
forms.py
from django import forms from .models import Inventory_unit_stock, Inventory_unit_catalog from dal import ModelSelect2Widget class InventoryStockAddForm(forms.ModelForm): # 在类级别声明所有字段 name = forms.CharField( max_length=96, widget=forms.TextInput(), required=True ) referenced_catalog = forms.ModelChoiceField( queryset=Inventory_unit_catalog.objects.none(), # 初始化为空QuerySet,后续动态更新 label="", widget=ModelSelect2Widget( model=Inventory_unit_catalog, search_fields=['name__icontains'], attrs={'data-placeholder': 'Select catalog...', 'data-width': '35em'} ), required=False ) def __init__(self, *args, **kwargs): # 取出user_context_id并设置默认值,避免KeyError self.user_context_id = kwargs.pop('user_context_id', None) super().__init__(*args, **kwargs) # 仅当user_context_id有效时,过滤QuerySet if self.user_context_id: self.fields['referenced_catalog'].queryset = Inventory_unit_catalog.objects.filter( parent_business_unit_context_id=self.user_context_id ) class Meta: model = Inventory_unit_stock fields = ('name', 'referenced_catalog') # 包含所有需要的字段
views.py
def your_stock_add_view(request): # 从当前请求的session获取值,设置默认值避免KeyError user_context_id = request.session.get('user_context_id') # 处理user_context_id不存在的情况(比如引导用户选择上下文) if not user_context_id: # 这里可根据业务逻辑处理,例如: # return redirect('context_selection_page') pass add_form = InventoryStockAddForm(user_context_id=user_context_id) # 后续的渲染或表单提交处理逻辑 # ...
关键说明
- 初始
queryset设为objects.none():避免Django在验证表单类时,因缺少user_context_id而抛出错误。 - 动态更新
queryset:确保只有在表单实例化时,才根据用户的上下文过滤数据。 - 给
user_context_id设置默认值:无论是从session获取还是传递给表单,都用默认值兜底,避免KeyError。 - Meta类包含所有字段:确保表单能正确识别并处理
referenced_catalog字段。
这样修改后,应该就能解决你遇到的验证错误和键值找不到的问题了。
内容的提问来源于stack exchange,提问作者qaccount345
相关产品推荐
相关产品推荐

