0

私はフォームを得ました:

class SearchForm(Form):
owner = ModelMultipleChoiceField(queryset=User.objects.all(), required=False)

関連ビューをカスタマイズした後get_queryset()、期待どおりに動作しますが、所有者のないオブジェクトを取得しました。リストの上に新しい選択肢を追加して、(0,'Without owner')所有者のいないオブジェクトのみをフィルタリングできるようにします。このオプションを追加するには?

更新: 選択肢を追加し、form.__init__カスタムのクリーン メソッドを作成しましたが、追加のオプションを選択すると、クリーン メソッドに到達する前に何かが発生ValidationErrorします。オーバーライドする必要があると推測していますform.is_validが、その方法がわからないので、デフォルトの is_valid メソッドを引き続き使用します。

私のコード

def __init__(self, *args, **kwargs):
    super(ClientListSearchForm, self).__init__(*args, **kwargs)
    self.fields['owner'].choices = \
        list(self.fields['owner'].choices)+[('0', 'n/a')]

def clean_owner(self):
    logger.debug('CLEAN_OWNER:')
    data = self.cleaned_data.get('owner')
    logger.debug('data: %s' % data)
    if data == 0:
        logger.debug('Data zero - not assigned')
        return data
    users = User.objects.all()
    if all(e in users for e in data):
        logger.debug('Data in users - validating ok')
        return data
    else:
        raise ValidationError('Incorrect owner')

私は試した:

def is_valid(self):
    try:
        super(ClientListSearchForm, self).is_valid()
    except ValidationError as e:
        logger.debug('val error: %s' % e.args)

しかし、それは例外の検証でもキャッシュでもありません

UPDATE2 カスタムバリデータを追加

def userWithEmpty(value):
    users = User.objects.values_list('pk').all()
    v =list()
    for va in value:
        v.append(int(va))
    u = list()
    for us in users:
        u.append(int(us[0]))
    if not (all(e in u for e in v)or v ==0):
        raise ValidationError('Invalid Value: %s' % value)

私のforループよりもイテラブルのすべての値を変換するより良い方法はありますか?

改善の余地がたくさんあるので、回答として投稿しませんでした。私が間違っていることについての暴言を待っています-そして私はそれをすべて感謝します...

動作が停止しました eee - バリデーターの前に何かがありますvalidators=[]

4

1 に答える 1

1

私は他のアプローチで終わった

class ModelMultipleChoiceWithEmptyField(ModelMultipleChoiceField):
def __init__(self, *args, **kwargs):
    super(ModelMultipleChoiceWithEmptyField, self).__init__(*args, **kwargs)
    self.choices = list(self.choices) + [('0', 'Brak')]

def clean(self, value):
    if self.required and not value:
        raise ValidationError(self.error_messages['required'], code='required')
    if value == [u'0']:
        return value
    return super(ModelMultipleChoiceWithEmptyField,self).clean(value)

それはずっときれいで、うまくいきます。自由に再利用して改善してください

于 2014-04-25T13:17:05.853 に答える