我正在尝试覆盖render_option
文件中Select
Widget类中存在的forms.py
方法。所以我在相应的Model表单类中添加了具有相同名称的方法。但它不起作用(这种方法无法覆盖)。我的forms.py
文件看起来像,
class CustomSelectMultiple(Select):
allow_multiple_selected = True
def render_option(self, selected_choices, option_value, option_label):
print 'Inside custom render_option\n\n'
if option_value is None:
option_value = ''
option_value = force_text(option_value)
if option_value in selected_choices:
selected_html = mark_safe(' selected="selected"')
if not self.allow_multiple_selected:
# Only allow for a single selection.
selected_choices.remove(option_value)
else:
selected_html = ''
return format_html('<option value="{}" data-img-src="www.foo.com" {}>{}</option>',
option_value,
selected_html,
force_text(option_label))
def render_options(self, choices, selected_choices):
print 'Inside custom render_options\n\n'
print self
print choices
# Normalize to strings.
selected_choices = set(force_text(v) for v in selected_choices)
output = []
for option_value, option_label in chain(self.choices, choices):
if isinstance(option_label, (list, tuple)):
output.append(format_html('<optgroup label="{}">', force_text(option_value)))
for option in option_label:
output.append(self.render_option(selected_choices, *option))
output.append('</optgroup>')
else:
output.append(self.render_option(selected_choices, option_value, option_label))
#print output
return '\n'.join(output)
def render(self, name, value, attrs=None, choices=()):
print 'Inside custom render\n\n'
if value is None:
value = []
final_attrs = self.build_attrs(attrs, name=name)
output = [format_html('<select multiple="multiple"{}>', flatatt(final_attrs))]
options = self.render_options(choices, value)
if options:
output.append(options)
output.append('</select>')
return mark_safe('\n'.join(output))
def value_from_datadict(self, data, files, name):
if isinstance(data, MultiValueDict):
return data.getlist(name)
return data.get(name)
class GuideUpdateForm(ModelForm):
def __init__(self, *args, **kwargs):
super(GuideUpdateForm, self).__init__(*args, **kwargs)
self.fields['date_modified'].widget = HiddenInput()
self.fields['point_of_interest'].widget = CustomSelectMultiple()
class Meta:
fields = ('name', 'image', 'point_of_interest', 'date_modified', )
model = Guide
我还尝试更改我的Meta
类,
class Meta:
fields = ('name', 'image', 'point_of_interest', 'date_modified', )
model = Guide
widgets = {
'point_of_interest': SelectMultiple(attrs={'data-img-src': 'www.foo.com'}),
}
但它仅将属性data-img-src
添加到select
标记,但不添加到option
标记内的所有select
标记。
请注意,SelectMultiple
类调用renderoptions
类的Select
方法,该方法进一步调用renderoption
方法,该方法没有attrs=None
关键字参数。< / p>
答案 0 :(得分:2)
判断您自己的解决方案,看起来您可能一直在寻找ModelChoiceField
self.fields['point_of_interest'] = forms.ModelChoiceField(widget=CustomSelectMultiple(),
queryset=poi.objects.all())
queryset参数由&#34;模型对象的QuerySet组成,从中可以派生字段的选项,并且将用于验证用户的选择。&#34;
是否会创建一个id元组名称列表?因为我希望选项标记看起来像
option value="id">name</option>
我非常确定默认值为id, __str__
,其中__str__
是模型的字符串表示形式。如果您希望此名称特定于该名称,则可以覆盖此字段并设置label_from_instance
class MyModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return obj.name
答案 1 :(得分:1)
我设法通过将db值传递给choices
kwargs来解决这个问题。
from models import poi
class GuideUpdateForm(ModelForm):
def __init__(self, *args, **kwargs):
super(GuideUpdateForm, self).__init__(*args, **kwargs)
self.fields['date_modified'].widget = HiddenInput()
self.fields['point_of_interest'] = forms.ChoiceField(widget=CustomSelectMultiple(), choices=[(i.id,i.name) for i in poi.objects.all()])