
フォームは、Djangoで最もおいしいものの1つです(モデル、管理パネル、URLルーティングなどの後)。 以下は、それらを使用するための小さいながらも役立つガイドです。これは、フォームをプログラミングするときの8つの一般的な状況の分析です。
- チャレンジ 。 最も単純なフォームを確認して表示します。
Copy Source | Copy HTML<br/> class UserForm (forms.Form):<br/> username = forms.CharField()<br/> joined_on = forms.DateField() <br/>
このコードは、2つのテキストフィールド、それらに含まれるデータ、および入力された日付の正確さを表示します。
>
- チャレンジ 。 値が特定のパラメーターに依存するフォームを作成します。 たとえば、特定のサブドメインに関連する値を表示できます。
Copy Source | Copy HTML<br/> class UserForm (forms.Form):<br/> username = forms.CharField()<br/> plan = forms.ModelChoiceField(queryset = Plan.objects.none())<br/> <br/> def __init__ (self, subdomain, *args, **kwargs):<br/> self .default_username = default_username<br/> super ( UserForm , self). __init__ (*args, **kwargs)<br/> self .fields[ 'plan' ].queryset = Plan.objects. filter (subdomain = subdomain) <br/>
ここで__init__メソッドでは 、 プランフィールドの標準クエリセットをオーバーライドします。 同様に、すべての属性を完全に再定義できます。注意深い読者。選択はsuper(UserForm、self).__ init __(* args、** kwargs)を呼び出した後にのみ発生することにも注意してください。
>
- チャレンジ 。 再利用可能なフォーム。 clean_dataでデータを処理しています 。
Copy Source | Copy HTML<br/> class UserForm (forms.Form):<br/> username = forms.CharField()<br/> <br/> def save (self):<br/> data = self .cleaned_data<br/> user = User.objects.create(username = data[ 'username' ])<br/> #create a profile <br/> UserProfile.objects.create(user = user, ...some more data...) <br/>
このメソッドには好きな名前を付けることができますが、 ModelFormとの類似性を保つために通常saveと呼ばれます 。
>
- チャレンジ 。 独自の検証タイプを持つフィールドを持つフォームを作成します 。
Copy Source | Copy HTML<br/> class UserForm (forms.Form):<br/> username = forms.CharField()<br/> <br/> def clean_username (self):<br/> data = self .cleaned_data<br/> try :<br/> User.objects.get(username = data[ 'username' ])<br/> except User.DoesNotExist:<br/> return data[ 'username' ]<br/> raise forms.ValidationError( 'This username is already taken.' ) <br/>
ユーザー名の一意性の確認は次のとおりです。
>
- チャレンジ 。 フィールドの相互検証を伴うフォームの作成 。
Copy Source | Copy HTML<br/> class UserForm (forms.Form):<br/> username = forms.CharField()<br/> <br/> password1 = forms.PasswordField()<br/> password2 = forms.PasswordField()<br/> <br/> def clean (self):<br/> data = self .cleaned_data<br/> if "password1" in data and "password2" in data and data[ "password1" ] != data[ "password2" ]:<br/> raise forms.ValudationError( "Passwords must be same" ) <br/>
2つのフィールドのパスワードは、互いに同一性が確認されます。
>
- チャレンジ 。 データベースの特定の値に依存するフィールドを持つフォームを作成します。 たとえば、ユーザーごとに異なるフォームを表示する必要がある場合があります 。
Copy Source | Copy HTML<br/> def get_user_form_for_user (user):<br/> class UserForm (forms.Form):<br/> username = forms.CharField()<br/> fields = user .get_profile().all_field()<br/> #Use field to find what to show. <br/>
この場合の解決策は、フォームを動的に作成することです。
>
- チャレンジ 。 複数のモデルで動作するHTMLフォームの作成 。
Copy Source | Copy HTML<br/> #in forms.py <br/> class UserForm (forms.ModelForm):<br/> class Meta :<br/> model = User<br/> fields = [ "username" , "email" ]<br/> <br/> class UserProfileForm (forms.ModelForm):<br/> class Meta :<br/> model = UserProfile<br/> <br/> #in views.py <br/> def add_user (request):<br/> ...<br/> if request.method == "POST" :<br/> uform = UserForm (data = request.POST)<br/> pform = UserProfileForm (data = request.POST)<br/> if uform.is_valid() and pform.is_valid():<br/> user = uform.save()<br/> profile = pform.save(commit = False)<br/> profile .user = user<br/> profile .save()<br/> ....<br/> ...<br/> <br/> #in template <br/><form method= "post" ><br/> {{ uform.as_p }}<br/> {{ pform.as_p }}<br/> <input type= "submit" ...><br/></form> <br/>
>
- チャレンジ 。 1つのページで同じタイプの複数のフォームを使用する。 たとえば、調査を作成するときに、すべての質問を1ページに表示する必要がある場合があります 。
Copy Source | Copy HTML<br/> #IN views.py <br/> def survey (request, survey_slug)<br/> ...<br/> questions = survey .questions. all ()<br/> question_forms = []<br/> for question in questions:<br/> qform = QuestionForm(question=question, prefix = question.slug)<br/> question_forms.append(qform)<br/> ...<br/> if request.method == "POST" :<br/> for question in questions:<br/> qform = QuestionForm(question=question, prefix = question.slug, data = request.POST)<br/> #Validate and do save action <br/> ...<br/> ... <br/>
この状況では、 prefix属性が非常に役立ちます。
もちろん、フォームの詳細については、 ドキュメントを参照してください 。