问题描述
代码:(其中AddressInput是MultiWidget)
The code: (where AddressInput is a MultiWidget)
class AddressInput(widgets.MultiWidget):
def __init__(self, attrs=None):
self.widgets = widgets.HiddenInput(attrs), widgets.TextInput(attrs) # note that the second widget would be customized, I'm only providing simplified example, which does produce the same error
super().__init__(self.widgets, attrs)
def decompress(self, value):
try:
address = AddressPoint.objects.get(pk=value)
except (AddressPoint.DoesNotExist, ValueError):
address = None
return [value, str(address)]
def value_from_datadict(self, data, files, name):
return tuple(widget.value_from_datadict(data, files, f'{name}_{i}') for i, widget in enumerate(self.widgets))
class AddressFormField(MultiValueField):
widget = AddressInput
def __init__(self, queryset, empty_label="---------", to_field_name=None, limit_choices_to=None, *args, **kwargs):
fields = (
ModelChoiceField(queryset, empty_label=empty_label, to_field_name=to_field_name, limit_choices_to=limit_choices_to, *args, **kwargs),
CharField()
)
super().__init__(fields=fields, require_all_fields=False, *args, **kwargs)
#self.widget.choices = self.fields[0].widget.choices #### if not commented out, I get another error: AttributeError: 'RelatedFieldWidgetWrapper' object has no attribute 'decompress'
def compress(self, data_list):
if not data_list[1]:
return None
if not data_list[0]:
raise ValidationError('Invalid address')
return data_list[0]
class AddressForeignKey(ForeignKey):
def formfield(self, **kwargs):
# This is a fairly standard way to set up some defaults
# while letting the caller override them.
defaults = {'form_class': AddressFormField}
defaults.update(kwargs)
return super().formfield(**defaults)
我收到此错误:AttributeError:'AddressInput'对象没有属性'choices'因为ModelChoiceField没有声明它.将小部件传递给ModelChoiceField无效,因为如果它是实例,则它将进行复制.因此,正如您在注释掉的代码中所看到的,我手动设置了choices属性.但是然后我又遇到了另一个我无法解决的错误:AttributeError:'RelatedFieldWidgetWrapper'对象没有属性'decompress'
I get this error: AttributeError: 'AddressInput' object has no attribute 'choices'Because ModelChoiceField did not declare it. Passing the widget to ModelChoiceField does not work as it makes a copy if it's an instance.Thus I set the choices attribute manually as you can see in the commented out code.But then I got another error which I didn't resolve: AttributeError: 'RelatedFieldWidgetWrapper' object has no attribute 'decompress'
推荐答案
是否要将其作为Django中的Widget?
Do you want to make this as Widget in Django?
<input type="text" name="example" list="exampleList">
<datalist id="exampleList">
<option>hello</option>
<option>there</option>
</datalist>
如果您这样做,可以进行检查.
if you do, you can check this.
class ListTextWidget(forms.TextInput):
def __init__(self, data_list, name, *args, **kwargs):
super().__init__(*args, **kwargs)
self._name = name
self._list = data_list
self.attrs.update({'list':'list_%s' % self._name, 'autocomplete':'off'})
def render(self, name, value, attrs=None):
text_html = super().render(name, value, attrs=attrs)
data_list = '<datalist id="list_%s">' % self._name
for item in self._list:
data_list += '<option value="%s">' % item
data_list += '</datalist>'
return (text_html + data_list)
class ExampleForm(ModelForm)
...
include = ['exampleOne', ...]
widgets = {
'exampleOne': ListTextWidget(data_list=yourModel.objects.all(),name='exampleOne')
}
这篇关于MultiValueField不适用于ModelChoiceField的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!