Django中ModelChoiceField过滤查询集时'self'未定义的NameError修复
解决Django表单__init__方法的NameError错误及相关问题
核心错误原因
你在ConvForm里把__init__方法错误地定义成了内部类(多余添加了class关键字),导致Python无法识别这是类的初始化方法,自然找不到self参数,直接抛出NameError。
修正forms.py代码
移除__init__前的class关键字,将其改为类的初始化方法:
from django import forms from .models import Measure class ConvForm(forms.Form): from_value = forms.DecimalField(label='From Value', max_digits=256, decimal_places=255) from_measure = forms.ModelChoiceField(queryset=Measure.objects.none()) # 去掉多余的class关键字,定义为类的初始化方法 def __init__(self, *args, **kwargs): id = kwargs.pop('id') super().__init__(*args, **kwargs) self.fields['from_measure'].queryset = Measure.objects.filter(typeid=id)
修正views.py中的潜在问题
除了表单的错误,你的视图还有两处问题需要修复:
- GET请求时实例化
ConvForm未传入id参数,会导致表单初始化失败 request.from_type不是Django HttpRequest的默认属性,直接判断会报错;跳转逻辑不完整,缺乏默认跳转地址
修正后的views.py代码:
from django.shortcuts import render, redirect, get_object_or_404 from .models import Type, Measure from .forms import ConvForm def type(request, id): mytypes = Type.objects.all().values() # 用get_object_or_404替代get,避免id不存在时抛出异常 mytype = get_object_or_404(Type, id=id) mymeasures = Measure.objects.filter(typeid=id) if request.method == 'GET': # GET请求时必须传入id参数给表单 form = ConvForm(id, request.GET) if form.is_valid(): # 在这里编写表单数据处理逻辑 # ... # 用redirect生成跳转URL,避免硬编码路径 return redirect('type', id=id) else: form = ConvForm(id) context = { 'form' : form, 'mytype': mytype, 'mytypes' : mytypes, 'mymeasures' : mymeasures } # 用render简化模板渲染流程,无需手动加载模板和生成HttpResponse return render(request, 'type.html', context)
补充说明
- 使用
get_object_or_404替代Type.objects.get(id=id),当传入的id不存在时会返回标准404页面,更符合Web应用的错误处理逻辑 - 用
redirect生成跳转地址,避免硬编码URL路径,提升代码可维护性 - 移除手动加载模板的冗余代码,改用Django内置的
render函数简化视图逻辑
内容的提问来源于stack exchange,提问作者MODaly
相关产品推荐
相关产品推荐

