如何在Django的forms.py中获取request.session.get[]变量值
解决Django Form中用request.session填充ModelChoiceField的问题
你不能直接在ModelChoiceField的定义中使用self.session,因为Form类初始化时默认不接收request对象,也没有session属性。正确的做法是重写Form的__init__方法,传入request并动态设置字段的queryset。
修改后的forms.py代码
from django import forms from .models import AssetTag, Asset class AssetTagForm(forms.ModelForm): # 先初始化空的queryset,后续在__init__中动态赋值 assets = forms.ModelChoiceField( widget=forms.Select(attrs={'class': 'form-control'}), queryset=Asset.objects.none() ) class Meta: model = AssetTag fields = '__all__' labels = { 'tag':'Asset Tag', } exclude = ['created_by',] widgets = { 'branch':forms.CheckboxSelectMultiple(attrs={}), 'code':forms.TextInput(attrs={'class':'form-control', 'placeholder':'Code','readonly':'readonly'}), 'tag':forms.TextInput(attrs={'class':'form-control', 'placeholder':'Asset Tag'}), 'status':forms.Select(attrs={'class':'form-control'}), } def __init__(self, *args, **kwargs): # 从kwargs中取出request,避免传给父类__init__引发错误 self.request = kwargs.pop('request', None) super().__init__(*args, **kwargs) # 从session中安全获取branch,用get避免KeyError if self.request: branch = self.request.session.get('branch') if branch: self.fields['assets'].queryset = Asset.objects.filter(branch=branch)
在视图中实例化表单
在视图函数或类视图中,必须把request传给表单:
# 函数视图示例 def create_asset_tag(request): if request.method == 'POST': form = AssetTagForm(request=request, data=request.POST) if form.is_valid(): form.save() # 后续跳转或响应逻辑 else: form = AssetTagForm(request=request) return render(request, 'your_template.html', {'form': form})
关键说明
- 重写
__init__时要先弹出request参数,因为父类__init__不接受该参数,直接传递会报错。 - 使用
request.session.get('branch')而非直接取值,能避免session中无branch键时抛出KeyError。 - 若session中没有
branch,assets字段的queryset会保持为空,你可根据需求添加默认逻辑(比如显示全部资产或提示用户)。
内容的提问来源于stack exchange,提问作者shyam rathod
相关产品推荐
相关产品推荐

