可以说我有这样的表格:
class ChangeParentCIForm(ModelForm):
class Meta:
model = CINodeInventory
fields = ('parent',)
widgets = {'parent': AutocompleteWidget('inventory.uuid'),}
问题是,在我的情况下,AutocompleteWidget 内容不仅必须与“父”字段值相关,还必须与用户会话信息相关(对我来说,是用户在另一个页面上选择的数据库版本号)
为此,我在基于类的视图中做了这样的事情:
class CompanyManageChangeParentCIView(CompanySelectedMixin,CIContextMixin,CompanyViewCIMixin,UpdateView):
template_name = 'inventory/browse_change_parent_ci.html'
context_object_name = 'ci'
form_class = ChangeParentCIForm
def get_form(self,form_class):
form = super(CompanyManageChangeParentCIView,self).get_form(form_class)
form.base_fields['parent'].widget.url_params={'version':self.request.session['use_version']}
return form
当然,我修改了 AutocompleteWidget 代码来处理这个 'url_params' 额外参数。
它可以工作,但是这段代码在我看来并不是很漂亮,因为它修改了在初始化时为一个也在初始化时生成的字段创建的小部件。换句话说,如果您创建了 2 个表单实例,它指向相同的字段和小部件,所以如果我这样做:
def get_form(self,form_class):
form1 = super(CompanyManageChangeParentCIView,self).get_form(form_class)
form2 = super(CompanyManageChangeParentCIView,self).get_form(form_class)
form1.base_fields['parent'].widget.url_params="val1"
form2.base_fields['parent'].widget.url_params="val2"
print id(form1),id(form1.base_fields['parent'].widget)
print id(form2),id(form2.base_fields['parent'].widget)
可以看到 form1 和 form2 指向不同的实例,但它们指向相同的小部件(如果打印它们的 id,它们指向相同的字段)。所以对我来说,如果我将 form1 和 form2 显示到同一个模板中,我将显示 2 个小部件“AutocompleteWidget”,但都是使用最新修改自定义的,即 url_parms="val2"
即使我显示一种形式,在我看来也很危险,如果 2 个线程正在执行具有 2 个不同“url_params”值的相同代码的同一个小部件,会发生什么?
所以这是我的问题:如何自定义一个带有上下文信息的 django 小部件渲染,而不仅仅是它的相关字段值?