1

インラインで使用される MultiValueField を設定しました。MultiValueField を空白のままにすると、まだ入力されていると思われるように見えます。その結果、フォームに関する限り、これらのインラインは空ではない (したがって検証される) ため、フォーム検証エラーが発生し続けます。

だから私は疑問に思っていると思います:検証エラーの発生を避けることができるように、明示的に空白にできるように MultiValueField を設定するためのトリックはありますか?

問題のコードは次のとおりです。

class TypedValueField(forms.MultiValueField):
    def __init__(self, *args, **kwargs):
        fields = (
                  forms.ChoiceField(required=False, choices=[(None, '(type)')] + [(c,c) for c in ['int','float','bool','string']]),
                  forms.CharField(required=False)
                  )
        super(TypedValueField, self).__init__(fields, *args, **kwargs)


    def compress(self, data_list):
        if data_list:
            # Raise a validation error if time or date is empty
            # (possible if SplitDateTimeField has required=False).
            if data_list[1]=="" or data_list[1]==None:
                return data_list[1]
            if data_list[0] == 'bool':
                try:
                    if data_list[1].lower() == "true":
                        return True
                except:
                    pass
                try:
                    if int(data_list[1] == 1):
                        return True
                except ValueError:
                    raise forms.ValidationError("You must enter True or False")
                return False
            if data_list[0] == 'int':
                try:
                    return int(data_list[1])
                except ValueError:
                    raise forms.ValidationError("You must enter a number")
            if data_list[0] == 'float':
                try:
                    return float(data_list[1])
                except ValueError:
                    raise forms.ValidationError("You must enter a decimal number")
            if data_list[0] == 'string':
                return data_list[0]
            else:
                raise forms.ValidationError("Invalid data type")
        return None


class TypedValueWidget(forms.MultiWidget):
    def __init__(self, attrs=None):
        widgets = (
            forms.Select(choices=[(None, '(type)')] + [(c,c) for c in ['int','float','bool','string']]),
            forms.TextInput()
        )
        super(TypedValueWidget, self).__init__(widgets, attrs)

    def decompress(self, value):
        if value:
            if isinstance(value, bool):
                return ['bool', value]
            if isinstance(value, float):
                return ['float', value]
            if isinstance(value, int):
                return ['int', value]
            if isinstance(value, basestring):
                return ['string', value]
            else:
                raise Exception("Invalid type found: %s" % type(value))
        return [None, None]

class ParamInlineForm(forms.ModelForm):
    match = TypedValueField(required=False, widget=TypedValueWidget())

    class Meta:
        model = Param
4

2 に答える 2

0

これが私の問題でした。

        fields = (
                  forms.ChoiceField(required=False, choices=[(None, '(type)')] + [(c,c) for c in ['int','float','bool','string']]),
                  forms.CharField(required=False)
                  )

に変更する必要がありました

        fields = (
                  forms.ChoiceField(required=False, choices=[("", '(type)')] + [(c,c) for c in ['int','float','bool','string']]),
                  forms.CharField(required=False)
                  )

None選択肢フィールドの選択肢の値として使用すると、次のようにレンダリングされます。

<option value="None">(type)</option>

それ以外の

<option value="">(type)</option>

Django の有罪のソース コードは次のとおりです (Selectウィジェット クラスのrender_optionメソッド内)。

        return u'<option value="%s"%s>%s</option>' % (
            escape(option_value), selected_html,
            conditional_escape(force_unicode(option_label)))

None値として指定して元に戻したい状況は考えられません"None"。もちろん、空の値""も とは異なりNoneます。

于 2011-08-29T22:45:01.667 に答える
0

のクリーンメソッドをオーバーライドしますMutliValueField
(djangoソースを調べてください)

于 2011-08-27T14:17:38.063 に答える