如何在Django的ModelChoiceField中使用request.user?解决未定义错误
解决Django中ModelChoiceField用request.user过滤查询集的NameError问题
错误原因很明确:表单类在定义时处于模块加载阶段,此时request对象还未创建,直接在类级别的queryset中引用request.user必然会报NameError。下面是两种可行的解决方式:
方式一:在表单的__init__方法中动态设置查询集
修改你的AlbumForm,让它在初始化时接收request参数,然后动态过滤查询集:
from django import forms from .models import Album class AlbumForm(forms.Form): # 先初始化一个空的查询集 album = forms.ModelChoiceField(queryset=Album.objects.none()) def __init__(self, *args, **kwargs): # 从参数中取出request,注意要在调用super之前 self.request = kwargs.pop('request') super().__init__(*args, **kwargs) # 动态设置当前用户的相册查询集 self.fields['album'].queryset = Album.objects.filter(user=self.request.user)
然后修改视图中实例化表单的代码:
- 在
get_context_data方法中:
context['album_form'] = AlbumForm(request=self.request)
- 在
post方法中:
album_form = AlbumForm(data=request.POST, request=request)
方式二:在视图中实例化表单后修改查询集
如果不想改动表单的结构,也可以在视图中实例化表单后,再动态修改字段的查询集:
首先保持表单的基础定义:
from django import forms from .models import Album class AlbumForm(forms.Form): album = forms.ModelChoiceField(queryset=Album.objects.all())
然后修改视图代码:
- 在
get_context_data方法中:
album_form = AlbumForm() # 过滤当前用户的相册 album_form.fields['album'].queryset = Album.objects.filter(user=self.request.user) context['album_form'] = album_form
- 在
post方法中:
album_form = AlbumForm(data=request.POST) # 同样要设置查询集,否则表单验证时会出错 album_form.fields['album'].queryset = Album.objects.filter(user=request.user)
额外提示
你的视图代码中有个拼写错误:HtppResponseRedirect应该改成HttpResponseRedirect,记得导入from django.http import HttpResponseRedirect,否则会出现新的错误。
内容的提问来源于stack exchange,提问作者Adamu Abdulkarim Dee
相关产品推荐
相关产品推荐

