pythonのフレームワークであるdjangoはフォームを簡単に作ることができます。
まずmodels.pyでフォームで使う項目を設定し、その後forms.pyで送信フォームを作成すればhtml部分でフォームが使用できるようになります。
僕が以前作ったwebアプリケーションの例でやってみましょう。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from django.db import models
from django.utils import timezone
class Post(models.Model):
class Meta:
verbose_name = '投稿'
verbose_name_plural = '投稿リスト'
name = models.CharField('名前', max_length=20, default='ベルマーレ大好き')
text = models.TextField('本文')
date = models.DateTimeField('日付', default=timezone.now)
file = models.FileField('ファイル', null=True,blank=True)
good = models.IntegerField(default=0)
def __str__(self):
return self.text
#!/usr/bin/env python
# -*- coding: utf-8 -*-
これは文字化け対策のおまじない。.pyファイルにはすべてつけておくといいかも。
from django.db import models
from django.utils import timezone
上はdjangoでモデルを使用するために必要。下は時間を扱うライブラリですね。
class Post(models.Model):
class Meta:
verbose_name = '投稿'
verbose_name_plural = '投稿リスト'
class Post以下がいよいよモデルの中身ですが、class Meta以下を設定しておくと管理画面の名前を変更できます。
name = models.CharField('名前', max_length=20, default='ベルマーレ大好き')
text = models.TextField('本文')
date = models.DateTimeField('日付', default=timezone.now)
file = models.FileField('ファイル', null=True,blank=True)
good = models.IntegerField(default=0)
def __str__(self):
return self.text
そしてこれがモデルの項目。
名前があって本文があって日付入力欄があってファイルアップローダーがあって画像アップロードがあります。
画像掲示板ですね。
models.CharFieldとかmodels.TextFieldとかはモデルの属性ですね。
TextFieldはテキストで大量の文章を入力可能。CharFieldは255文字が限界なんだっけな???
あとformを作った時にCharFieldは細長いテキスト入力フォームになるけれど、TextFieldは大きなテキスト入力フォームに変換されますよ。
def __str__(self):
return self.text
は管理画面の一覧画面がtextで見られるようになるので見やすいです。
models.pyを作成したらその内容を保持したフォームが作成できるようになります。
forms.pyはこのように記載。
from django import forms
from django.views import generic
from .models import Post
class PostForm(forms.ModelForm):
file = forms.FileField(required=False)
#fileアップロード部分のラベルを消去
file = forms.FileField(
label='',
required=False,
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields.values():
field.widget.attrs['class'] = 'form-control'
class Meta:
model = Post
fields = ('name', 'text', 'file')
はい!解説。
from django import forms
from django.views import generic
from .models import Post
まず一行目でフォームを使えるようにdjangoのフォーム機能をインポートしています。
3行目は先ほど作成したmodels.pyからPostモデルををインポートしています。
2行目・・・。2行目これいる?コメントアウトして使ったら普通に機能しましたw
これってviews.pyで使うやつだよねえ???わからんw
class PostForm(forms.ModelForm):
file = forms.FileField(required=False)
#fileアップロード部分のラベルを消去
file = forms.FileField(
label='',
required=False,
)
続いてフォームを使用するクラス内の解説。
file = forms.FileField(required=False)
↑↑↑これないとコメントのみで(画像なし)でフォーム送信できないんですよね~。
#fileアップロード部分のラベルを消去
file = forms.FileField(
label='',
required=False,
)
デフォルトだとフォームの横にnameとかtextとか出てきてしまうのでそれを空欄にします。
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields.values():
field.widget.attrs['class'] = 'form-control'
これはフォームをかっこよくカスタマイズしてくれるBootstrap CheatSheatをつかうためのコード。
ただなぜこう書くと適用されるのかさっぱり分かっていません。
def initとか(self, *args, **kwargs):あたりの構文はいつかちゃんと勉強しなきゃと思っています。
class Meta:
model = Post
fields = ('name', 'text', 'file')
model = Postで仕様モデルを定義します。
fields = ('name', 'text', 'file')で実際にフォームで使用する項目を選択。
dateは投稿者に選択させるのではなく現在時刻を自動入力してくれればいいのではずしています。
goodを含んでしまうとgoodボタンを押さないと投稿できなくなるので外しています。
いいねボタンって普通投稿フォームと独立してるでしょ?
<form action="" method="POST" enctype="multipart/form-data">
{{ form.as_p }}
<button type="submit">送信</button>
{% csrf_token %}
</form>
ここではテンプレート側。html部分の解説。
なんとこれだけでフォームが出現します!!
{{ form.as_p }}
と書くだけでフォームが出現します。すげえ・・・。
<form action="" method="POST" enctype="multipart/form-data">
</form>
これがないとフォームは出現しても送信できません。
さらに下のコードは画像の送信に必須。
enctype="multipart/form-data"
これは送信ボタン。
<button type="submit">送信</button>
このコードでフォームを使ったサイトへの攻撃から守ってくれます。どういう仕組みなのかいつか勉強したい!
{% csrf_token %}
これでdjangoでフォームを出現させることができます!!
補足
ミスりました。
views.pyにフォームのクラスを作って
from .forms import PostForm
class クラス名(CreateView):
model = Post
form_class = PostForm
template_name = "使用したいテンプレート名"
success_url = "リダイレクトするURL"
として
urls.pyに
path('使いたいURL', views.クラス名.asview(),name='使いたい名前'),
ってしなきゃダメでした。
ごめん!