我有一个带有自定义表单字段的Django应用程序,其中一些在构造函数中运行缓慢.我最近惊讶地发现,当Django本身启动时,那些构造函数会被调用,甚至在用户在视图中执行需要该表单的操作之前.
为什么他们在服务器启动时被实例化?
例:
urls.py:
from myapp.views import view1
...
url(r'^test$', view1.test),
Run Code Online (Sandbox Code Playgroud)
意见/ view1.py:
class MyForm(ModelForm):
class Meta:
model = MyModel
field1 = MyChoiceField()
class MyChoiceField(ChoiceField):
def __init__(self, choices=(), required=True, widget=None, label=None,
initial=None, help_text=None, *args, **kwargs):
super(ChoiceField, self).__init__(required, widget, label, initial,
help_text, *args, **kwargs)
self.choices = [(m.id, m.name) for m in ReallyLargeTableModel.objects.all()]
Run Code Online (Sandbox Code Playgroud)
如果我在该字段构造函数中设置了一个断点,然后启动Django,它会在我第一次请求任何页面时中断,即使所讨论的视图不需要该表单或字段.stacktrace返回urls.py中的导入行.
这是因为我在urls.py中导入view1,而不是导入view1.test?
编辑:这不是Django特有的,这里是一个测试用例说明行为:
class Something():
def __init__(self):
print "Something __init__() called"
class UsesSomething():
field = Something()
Run Code Online (Sandbox Code Playgroud)
如果在交互式终端中运行它,它将打印"Something init()called".这对我来说是令人惊讶的,因为我实际上没有实例化一个UsesSomething对象.
因为您实例化了表单定义中的字段,这可能是由您的某个视图导入的.
出于这个原因,字段init是进行这种动态初始化的错误位置.你想要在初始化表单时调用的东西:即表单__init__
.
也就是说,你实际上并不想这样做 - 你只需要使用forms.ModelChoiceField
,它需要一个查询集并为你做动态的选择.
class MyForm(ModelForm):
field1 = forms.ModelChoiceField(queryset=ReallyLargeTableModel.objects.all())
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1436 次 |
最近记录: |