在上一篇时,我们小试牛刀了以下Django Form组件的使用,一篇文章带你了解Django Form组件(入门篇),没来得及的小伙伴可以一起看看。但是你可能会有很多疑问,并不知道怎么使用。
并且知道Form组件的功能。
所以本篇就接着上次的继续,来一起学习以下Django Form组件如何使用。
Form组件的理解
没有使用Form组件时
在一般情况下,我们如果编写输入框时,在Html中,一般都是这样写的。
- ...
- <form method="post" action="" novalidate>
- <div>
- <label>用户名:</label>
- <input type="text" name="uname">
- </div>
- <div>
- <label>密码:</label>
- <input type="text" name="upwd">
- </div>
- <div><input type="submit"></div>
- </form>
- ...
使用Form组件时
在使用Form组件时,我们通常需要定义Form类。
这个Form,里面的字段,就可以理解为input标签,只不过是在后端写的。
Form类
- from django.forms import Form
- class LoginForm(Form):
- uname = fields.CharField(label="用户名")
- upwd = fields.CharField(label="密码")
views.py
- from django.shortcuts import render
- def login(request):
- form = LoginForm()
- return render(request, "login_f.html", {"form": form})
- ...
- <form method="post" action="" novalidate>
- <div>
- <label>{{ form.uname.label }}:</label>
- {{ form.uname }}
- <!--
- form.uname.errors.0 是为了展示填写不正确的错误信息
- errors.0是因为错误可能有多个
- 但是通常情况下,取第一个错误足够
- -->
- {{ form.uname.errors.0 }}
- </div>
- <div>
- <label>{{ form.upwd.label }}:</label>
- {{ form.upwd }}
- {{ form.upwd.errors.0 }}
- </div>
- <div><input type="submit"></div>
- </form>
- ...
可以发现,我并没有写input代码,而是直接调用后端的form.<字段名>出来的。
Form类生成的Html
可以发现,基本上和自己写的Html差不多,生成的id为id+<字段名>。
Form生成的Html和手动写Html对应图
通过对应图确定,通过后端的form.<字段>生成的直接就是input标签。
好了,到这,就确定了Form类,就是为我们生成input标签的。
Form使用
使用有以下步骤。
1.创建Form类,尽可能和models对上。
- class LoginForm(Form):
- uname = fields.CharField(label="用户名")
- upwd = fields.CharField(label="密码")
因为Form提交的数据,可以转换成dict,key就是Form字段名。
如果Form字段和models对上,直接models.<模型类>.objects.create(**dict)。
2.如果是GET请求,实例化Form对象,并且返回页面。
- def login(request):
- if request.method == 'GET':
- form = LoginForm()
- return render(request, "login_f.html", {"form": form})
3.如果是POST请求,实例化Form对象时,传入request.POST,request.FILES,并且验证。
- # 接着上面
- elif request.method == "POST":
- form = LoginForm(request.POST, request.FILES)
- ########### 验证数据
- if form.is_valid():
- # 验证成功
- # 验证成功之后的数据,key就是Form类的字段名
- print(form.cleaned_data) # {'uname': '1212', 'upwd': '1212'}
- return HttpResponse("ok")
- # 验证失败
- # 虽然返回的还是页面
- # 但是form会把上次输入框内容保存下来,并且还会展示errors信息
- return render(request, "login_f.html", {"form": form})
4.前端使用后端传过来的form对象。
方式一,点每个字段
- <form method="post" action="" novalidate>
- <div>
- <!-- form.uname.label点的是label属性 -->
- <label>{{ form.uname.label }}:</label>
- {{ form.uname }}
- <!--
- form.uname.errors.0 是为了展示填写不正确的错误信息
- errors.0是因为错误可能有多个
- 但是通常情况下,取第一个错误足够
- -->
- {{ form.uname.errors.0 }}
- </div>
- <div>
- <label>{{ form.upwd.label }}:</label>
- {{ form.upwd }}
- {{ form.upwd.errors.0 }}
- </div>
- <div><input type="submit"></div>
- </form>
方式二,循环form对象
form对象是可以循环的,循环的每个form对象就是每个字段对象。
- <form method="post" action="" novalidate>
- {% for foo in form %}
- <div>
- <label>{{ foo.label }}:</label>
- {{ foo }}
- {{ foo.errors.0 }}
- </div>
- {% endfor %}
- <div><input type="submit"></div>
- </form>
Form字段
Form组件主要是帮助我们做验证的,所以,当然有很多参数比如:
Field类为所有字段的基类
Field参数如下
CharField(Field),比较常用的字段之一
IntegerField(Field)
DecimalField(IntegerField)
其他字段还有
- BaseTemporalField(Field)
- DateField(BaseTemporalField)
- TimeField(BaseTemporalField)
- DateTimeField(BaseTemporalField)
- DurationField(Field)
- RegexField(CharField)
- EmailField(CharField)
- FileField(Field)
- ImageField(FileField)
- URLField(Field)
- BooleanField(Field)
- NullBooleanField(BooleanField)
...还有很多字段,这里就不一一赘述了,具体详见官网:
https://docs.djangoproject.com/zh-hans/2.0/ref/forms/api/#django.forms.BoundField
- ChoiceField(Field)
- ...
- choices=() # 选项,如:choices = ((1,'一班'),(2,'二班'),)
- required=True # 是否必填
- widget=None # 插件,默认select插件
- label=None # Label内容
- initial=None # 初始值
- help_text='' # 帮助提示
- from django.forms.models import ModelChoiceField
- # 单选
- ModelChoiceField(ChoiceField)
- queryset=None # 查询数据库中的数据
- empty_label="---------" # 默认空显示内容
- to_field_name=None # HTML中value的值对应的字段
- limit_choices_to=None # ModelForm中对queryset二次筛选
- # 多选
- from django.forms.models import ModelMultipleChoiceField
- ModelMultipleChoiceField(ModelChoiceField)
- ...
widget参数对应的插件
即使字段是CharField,但是最终效果以插件为主!
- TextInput(Input)
- NumberInput(TextInput)
- EmailInput(TextInput)
- URLInput(TextInput)
- PasswordInput(TextInput)
- HiddenInput(TextInput)
- Textarea(Widget)
- DateInput(DateTimeBaseInput)
- DateTimeInput(DateTimeBaseInput)
- TimeInput(DateTimeBaseInput)
- CheckboxInput
- Select
- NullBooleanSelect
- SelectMultiple
- RadioSelect
- CheckboxSelectMultiple
- FileInput
- ClearableFileInput
- MultipleHiddenInput
- SplitDateTimeWidget
- SplitHiddenDateTimeWidget
- SelectDateWidget
widget示例
- from django.forms import fields, widgets
- from django.forms import Form
- user = fields.CharField(
- initial=2,
- widget=widgets.RadioSelect(choices=((1,'一班'),(2,'二班'),))
- )
- # or
- user = fields.ChoiceField(
- choices=((1,'一班'),(2,'二班'),),
- initial=2,
- widget=widgets.RadioSelect
- )
- # 多选select,值为列表
- user = fields.MultipleChoiceField(
- choices=((1,'一班'),(2,'二班'),),
- initial=[1,],
- widget=widgets.SelectMultiple
- )
- # 从数据库中获取多选
- # 方式一
- from django.forms import Form
- from django.core.validators import RegexValidator
- class Form类(Form):
- user = fields.ChoiceField(
- # choices=((1,'一班'),(2,'二班'),),
- initial=2,
- widget=widgets.Select
- )
- def __init__(self, *args, **kwargs):
- super(MyForm,self).__init__(*args, **kwargs)
- # self.fields['user'].widget.choices = ((1,'一班'),(2,'二班'),)
- # 或
- self.fields['user'].widget.choices = models.Classes.objects.all().value_list('id','caption')
- # 方式二
- from django.forms import models as form_model
- class Form类(Form):
- depart = form_model.ModelMultipleChoiceField(queryset=models.Depart.objects.all())
本篇先从入门角度说如何使用简单使用Django Form组件,使用Form组件和没使用Form组件的区别。
然后讲了以下Form如何使用。
最后列举出常用的Form字段,还有如何使用多选字段。