実際、私が最初にしたことは、写真とビデオの撮影のための申込書を用意することでした。 この時点で、フレームワークに関する私の知識は、部門の内部サーバーにリストするためのいくつかのビューに限定されていました。 鉄の形の主な困難は
電話の入力フィールドから始めます。 最初はHabrに目を向けてポストを見つけましたが、私が見たものは、私にはあまりにも扱いにくいように思えました(電話をオペレーターに転送する必要があったためです)。 CharFieldを使用しても私の目標にはならないことに気付き、Djangoのドキュメントをざわめいて、さらにMultiValueFieldとMultiWidgetを見つけました(MultiValueFieldのみを使用すると、テキストを入力するための通常の文字列が生成されるため、意味がありません) 。 数分後、コードはカットの下で作成されました。
1)まず、必要なものをインポートします。
from django.forms import MultiValueField, CharField, ChoiceField, MultiWidget, TextInput, Select
2)次に、Widgetを定義します。PhoneWidgetの基本クラスはMultiWidgetです。
class PhoneWidget(MultiWidget): def __init__(self, code_length=3, num_length=7, attrs=None): widgets = [TextInput(attrs={'size': code_length, 'maxlength': code_length}), TextInput(attrs={'size': num_length, 'maxlength': num_length})] super(PhoneWidget, self).__init__(widgets, attrs) def decompress(self, value): if value: return [value.code, value.number] else: return ['', '']
少し説明:
サンクトペテルブルクとロシア全土のモバイルの都市コードの長さは3文字で、電話自体は7です。しかし、両方のパラメーターが変更される可能性があるため、コンストラクターで私に適したデフォルト値を指定しました。
次に、code_length(コード長)およびnum_length(数値の長さ)パラメーターを使用して、入力フィールドの長さ(美しさのため)および文字数(エラー保護のため)に制限がある2つのウィジェット自体(フィールド表現と呼ぶことができると思います)の定義があります。
美しさ
def format_output(self, rendered_widgets): return '+7' + '(' + rendered_widgets[0] + ') - ' + rendered_widgets[1]
htmlで美しい書式設定を取得するため。
3)MultiValueFieldの基本クラスとしてフィールド自体を定義します。
class PhoneField(MultiValueField): def __init__(self, code_length, num_length, *args, **kwargs): list_fields = [CharField(), CharField()] super(PhoneField, self).__init__(list_fields, widget=PhoneWidget(code_length, num_length), *args, **kwargs) def compress(self, values): return '+7' + values[0] + values[1] #,
少し説明:
コンストラクターには、ウィジェットコンストラクターに渡すための同じパラメーターが含まれています。 そうでなければ、私が書いたように、テキストを入力するための通常の文字列を取得します。
4)結果として、フォームのフィールドを示します
p_num = PhoneField() # \ : PhoneField(code_length=some_value, num_length=some_value)
そして、テンプレートに追加することにより
{{ form.p_num.errors }} <label for="phone_num"> :</label> </br> {{ form.p_num }}
長さ3文字と7文字(または表示される文字数)の2つの美しいフィールドと、標準化してユーザーにプロンプトを表示する国際コードが表示されます。
類推により、時間を入力するためのウィジェットとフィールドが作成されました。
class TimeWidget(MultiWidget): def __init__(self, h_choices, m_choices, attrs=None): widgets = [Select(choices=h_choices), Select(choices=m_choices)] super(TimeWidget, self).__init__(widgets, attrs) def decompress(self, value): if value: return [value.hours, value.minutes] else: return ['', ''] class TimeField(MultiValueField): def __init__(self, h_choices, m_choices, *args, **kwargs): list_fields = [ChoiceField(), ChoiceField()] super(TimeField, self).__init__(list_fields, widget=TimeWidget(h_choices, m_choices),*args, **kwargs) def compress(self, values): return return values[0] + ':' + values[1] # datetime
ユーザーが就業日の外の時間を表示するのを防ぎ、合理的な制限(24と60)を超えないように、パラメーターを選択して2つのリストを作成しました。
呼び出し:
time = TimeField(h_choices=HOURS_CHOICES, m_choices=MINUTES_CHOICES)
また、パラメーター自体(Djangoのドキュメントによると、タプルのリストであり、フォームクラスの外部で定義されている必要があります):
HOURS_CHOICES = [(str(x), x) for x in range(9, 21)] # , MINUTES_CHOICES = [(1, 0), (2, 10), (3, 20), (4, 30), (5, 40), (6, 50),] # - , - . .
フィールド間に記号区切り文字を挿入する方法を理解するだけです(たとえば、時間と分の間の ':')が、これには機能的な負荷はありません。 ただし、この問題を解決し、見つけた解決策とフィールドの他の例で投稿を補足しようとします。
UPD: format_output()メソッドは