我想要一个multiState点击框。所以我花了一些空闲的时间在一个很好的Django解决方案上:
DoctorObject model = (DoctorObject)getChild(groupPosition, childPosition);
String childText = model.getName();
这会创建一个类似于此处https://stackoverflow.com/a/33455783/3849359所说明的形式,然后点击切换下一个状态,直到它到达,然后在开头继续。
在我的视图中调用表单,如:
class MultiStateChoiceInput(forms.widgets.ChoiceInput):
input_type = 'radio'
def __init__(self, name, value, attrs, choice, index, label_id):
# Override to use the label_id which is upped with 1
if 'id' in attrs:
self.label_id = attrs['id']+ "_%d" % label_id
super(MultiStateChoiceInput, self).__init__(name, value, attrs, choice, index)
self.value = force_text(self.value)
@property
def id_for_label(self):
return self.label_id
def render(self, name=None, value=None, attrs=None, choices=()):
if self.id_for_label:
label_for = format_html(' for="{}"', self.id_for_label)
else:
label_for = ''
attrs = dict(self.attrs, **attrs) if attrs else self.attrs
return format_html(
'{} <label{}>{}</label>', self.tag(attrs), label_for, self.choice_label
)
class MultiStateRenderer(forms.widgets.ChoiceFieldRenderer):
choice_input_class = MultiStateChoiceInput
outer_html = '<span class="cyclestate">{content}</span>'
inner_html = '{choice_value}{sub_widgets}'
def render(self):
"""
Outputs a <ul> for this set of choice fields.
If an id was given to the field, it is applied to the <ul> (each
item in the list will get an id of `$id_$i`).
# upgraded with the label_id
"""
id_ = self.attrs.get('id')
output = []
for i, choice in enumerate(self.choices):
choice_value, choice_label = choice
if isinstance(choice_label, (tuple, list)):
attrs_plus = self.attrs.copy()
if id_:
attrs_plus['id'] += '_{}'.format(i)
sub_ul_renderer = self.__class__(
name=self.name,
value=self.value,
attrs=attrs_plus,
choices=choice_label,
label_id = (i+1) % (len(self.choices)) # label_id is next one
)
sub_ul_renderer.choice_input_class = self.choice_input_class
output.append(format_html(self.inner_html, choice_value=choice_value,
sub_widgets=sub_ul_renderer.render()))
else:
w = self.choice_input_class(self.name, self.value,
self.attrs.copy(), choice, i, label_id = (i+1) % (len(self.choices))) # label_id is next one
output.append(format_html(self.inner_html,
choice_value=force_text(w), sub_widgets=''))
return format_html(self.outer_html,
id_attr=format_html(' id="{}"', id_) if id_ else '',
content=mark_safe('\n'.join(output)))
class MultiStateSelectWidget(forms.widgets.RendererMixin, forms.widgets.Select):
''' This widget enables multistate clickable toggles
Requires some css as well (see .cyclestate)
'''
renderer = MultiStateRenderer
并且forms.py是:
SomeFormSet= modelformset_factory(myModel, form=myModelForm, extra=0)
SomeFormSet.form = staticmethod(curry(myModelForm, somevariable=somevariable))
formset = SomeFormSet(request.POST or None, queryset=somequeryset)
我觉得它运作得很好。点击和保存工作正常(我有一个自定义保存方法)。除非表单字段的值为2或3,否则它会突然显示错误消息:&#39; field&#39;应该是一个整数。
如果有人能提供帮助那就太好了,因为我没有想法!
编辑:以防万一......我已经检查了POST,这很棒。唯一的问题是Django在解析POST的某个地方完全丢失了值(它变为None)如果值是2并且我不知道为什么。EDIT2:似乎Django ModelForm也进行了模型验证。而模型是一个BooleanField,这就是它失败的原因。如果有人知道覆盖它的好方法,那就太好了!
答案 0 :(得分:0)
@edgarzamora你的评论不是答案,但它很接近!
我从Form类Meta中删除了'field',所以它看起来像:
class Meta:
model = MyModal
fields = ('',)
widgets = {'id': forms.HiddenInput(),
}
现在一切正常,因为我有我的自定义保存方法......太愚蠢了,它花了我几个小时!谢谢!