web-dev-qa-db-ja.com

空のラベルChoiceField Django

ChoiceFieldのラベルをModelChoiceFieldのように動作させるにはどうすればよいですか? _empty_label_を設定する方法、または少なくとも空白のフィールドを表示する方法はありますか?

Forms.py:

_    thing = forms.ModelChoiceField(queryset=Thing.objects.all(), empty_label='Label')
    color = forms.ChoiceField(choices=COLORS)
    year = forms.ChoiceField(choices=YEAR_CHOICES)
_

ここで提案した解決策を試しました:

スタックオーバーフローQ -CHOICES = [('','All')] + CHOICESを設定すると、内部サーバーエラーが発生しました。

スタックオーバーフローQ2 -選択で_('', '---------'),_を定義した後、_('', '---------'),_選択ではなく、リストの最初の項目がデフォルトのままです。

Gist -ここで定義されているEmptyChoiceFieldを使用して試してみましたが、Django 1.4。

しかし、これらのどれも私のために働いていません..この問題をどのように解決しますか?あなたのアイデアをありがとう!

35
Nick B

私が使用した解決策は次のとおりです。

from myapp.models import COLORS

COLORS_EMPTY = [('','---------')] + COLORS

class ColorBrowseForm(forms.Form):
    color = forms.ChoiceField(choices=COLORS_EMPTY, required=False, widget=forms.Select(attrs={'onchange': 'this.form.submit();'}))
15
Nick B

ChoiceField のDjango 1.11ドキュメントを参照してください。ChoiceFieldの 'empty_value'は空の文字列 ''として定義されているため、タプルのリストには、 ''空の値に対して表示する値にマッピングされます。

### forms.py
from Django.forms import Form, ChoiceField

CHOICE_LIST = [
    ('', '----'), # replace the value '----' with whatever you want, it won't matter
    (1, 'Rock'),
    (2, 'Hard Place')
]

class SomeForm (Form):

    some_choice = ChoiceField(choices=CHOICE_LIST, required=False)

'required = False'を使用してフォームフィールドをオプションにする場合は、フォームエラーを回避できます。

また、empty_valueのないCHOICE_LISTが既にある場合は、フォームのドロップダウンメニューに最初に表示されるように挿入できます。

CHOICE_LIST.insert(0, ('', '----'))
40
Fiver

あなたはこれを試すことができます(あなたの選択がタプルであると仮定して):

blank_choice = (('', '---------'),)
...
color = forms.ChoiceField(choices=blank_choice + COLORS)
year = forms.ChoiceField(choices=blank_choice + YEAR_CHOICES)

また、これがフォームであるかModelFormであるかをコードから知ることはできませんが、後者であるため、ここでフォームフィールドを再定義する必要はありません(モデルフィールドにchoices = COLORSおよびchoices = YEAR_CHOICESを直接含めることができます) 。

お役に立てれば。

3
reczy

私はあなたがすでに答えを受け入れていることを知っていますが、誰かが私が抱えていた問題に遭遇した場合、つまり受け入れられたソリューションがValueListQuerySetで動作しない場合にだけこれを投稿したいと思います。あなたがリンクした EmptyChoiceField は、私にとって完璧に機能します(ただし、Django 1.7)を使用しています)。

class EmptyChoiceField(forms.ChoiceField):
    def __init__(self, choices=(), empty_label=None, required=True, widget=None, label=None, initial=None, help_text=None, *args, **kwargs):

        # prepend an empty label if it exists (and field is not required!)
        if not required and empty_label is not None:
            choices = Tuple([(u'', empty_label)] + list(choices))

        super(EmptyChoiceField, self).__init__(choices=choices, required=required, widget=widget, label=label, initial=initial, help_text=help_text, *args, **kwargs) 

class FilterForm(forms.ModelForm):
    #place your other fields here 
    state = EmptyChoiceField(choices=People.objects.all().values_list("state", "state").distinct(), required=False, empty_label="Show All")
3
VT_Drew

パーティーに少し遅れて..

選択肢をまったく変更せず、ウィジェットで処理するだけではどうですか?

from Django.db.models import BLANK_CHOICE_DASH

class EmptySelect(Select):
    empty_value = BLANK_CHOICE_DASH[0]
    empty_label = BLANK_CHOICE_DASH[1]

    @property
    def choices(self):
        yield (self.empty_value, self.empty_label,)
        for choice in self._choices:
            yield choice

    @choices.setter
    def choices(self, val):
        self._choices = val

それからちょうどそれを呼ぶ:

class SomeForm(forms.Form):
    # thing = forms.ModelChoiceField(queryset=Thing.objects.all(), empty_label='Label')
    color = forms.ChoiceField(choices=COLORS, widget=EmptySelect)
    year = forms.ChoiceField(choices=YEAR_CHOICES, widget=EmptySelect)

当然、EmptySelectはある種のcommon/widgets.pyコード内に配置され、必要に応じて参照するだけです。

1
Javier Buzzi

モデルの整数フィールドのため、u ''の代わりに0を使用する必要がありました。 (エラーはベース10のint()のリテラルとして無効でした: ')

空のラベルが存在する場合は先頭に追加します(フィールドは不要です!)

    if not required and empty_label is not None:
        choices = Tuple([(0, empty_label)] + list(choices))
1
Pat

同じ形式ではありませんが、EmptyChoiceFieldメソッドに触発されて次のように行いました。

from Django import forms
from ..models import Operator


def parent_operators():
    choices = Operator.objects.get_parent_operators().values_list('pk', 'name')
    choices = Tuple([(u'', 'Is main Operator')] + list(choices))
    return choices


class OperatorForm(forms.ModelForm):
    class Meta:
        model = Operator
        # fields = '__all__'
        fields = ('name', 'abbr', 'parent', 'om_customer_id', 'om_customer_name', 'email', 'status')

    def __init__(self, *args, **kwargs):
        super(OperatorForm, self).__init__(*args, **kwargs)
        self.fields['name'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['abbr'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['parent'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['parent'].choices = parent_operators()
        self.fields['parent'].required = False
        self.fields['om_customer_id'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['om_customer_name'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['email'].widget.attrs.update({'class': 'form-control m-input form-control-sm', 'type': 'email'})enter code here
0
cwhisperer