前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一篇文章浅析Django Form组件相关知识

一篇文章浅析Django Form组件相关知识

作者头像
Python进阶者
发布2021-01-25 11:37:04
9440
发布2021-01-25 11:37:04
举报

灭烛怜光满,披衣觉露滋。

前言

在上一篇时,我们小试牛刀了以下Django Form组件的使用,一篇文章带你了解Django Form组件(入门篇),没来得及的小伙伴可以一起看看。但是你可能会有很多疑问,并不知道怎么使用。

并且知道Form组件的功能。

  • 生成HTML标签。
  • 验证提交的数据。
  • 保留提交之前的数据。

所以本篇就接着上次的继续,来一起学习以下Django Form组件如何使用。

Form组件的理解

没有使用Form组件时

在一般情况下,我们如果编写输入框时,在Html中,一般都是这样写的。

代码

代码语言:javascript
复制
...
<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类

代码语言:javascript
复制
from django.forms import Form
class LoginForm(Form):
    uname = fields.CharField(label="用户名")
    upwd = fields.CharField(label="密码")

views.py

代码语言:javascript
复制
from django.shortcuts import render
def login(request):
    form = LoginForm()
    return render(request, "login_f.html", {"form": form})

html

代码语言:javascript
复制
...
<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对上。

代码语言:javascript
复制
class LoginForm(Form):
    uname = fields.CharField(label="用户名")
    upwd = fields.CharField(label="密码")

因为Form提交的数据,可以转换成dict,key就是Form字段名。

如果Form字段和models对上,直接models.<模型类>.objects.create(**dict)

2.如果是GET请求,实例化Form对象,并且返回页面。

代码语言:javascript
复制
def login(request):
    if request.method == 'GET':
        form = LoginForm()
        return render(request, "login_f.html", {"form": form})

3.如果是POST请求,实例化Form对象时,传入request.POST,request.FILES,并且验证。

代码语言:javascript
复制
# 接着上面
    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对象。

方式一,点每个字段

代码语言:javascript
复制
<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对象就是每个字段对象。

代码语言:javascript
复制
<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组件主要是帮助我们做验证的,所以,当然有很多参数比如:

  • 否可以为空。
  • label展示的内容。
  • 等...

常用字段

Field类为所有字段的基类

Field参数如下

  • required=True,是否允许为空,默认True,不能为空
  • widget=None,插件,展示的input具体信息
  • label=None,label,标签展示的内容
  • help_text="",帮助信息(在标签旁边显示)
  • error_massages=None,错误信息{"required":"不能为空",...}
  • show_hidden_initial=False,是否在当前插件后再加一个隐藏且具有默认值的插件(可用于验证两次输入是否一致)
  • validators=[],自定义验证规则函数
  • localize=False,是否支持本地化
  • disabled=False,是否可以编辑
  • label_suffix=None,Label内容后缀

CharField(Field),比较常用的字段之一

  • min_length=None,最小长度
  • max_length=None,最大长度
  • strip=True,是否移除输入空白

IntegerField(Field)

  • max_value=None,最大值
  • min_value=None,最小值

DecimalField(IntegerField)

  • max_value=None,最大值
  • min_value=None,最小值
  • max_digits=None,最大长度
  • decimal_places=None,小数位长度

其他字段还有

代码语言:javascript
复制
BaseTemporalField(Field)
DateField(BaseTemporalField)
TimeField(BaseTemporalField)
DateTimeField(BaseTemporalField)
DurationField(Field)
RegexField(CharField)
EmailField(CharField)
FileField(Field)
ImageField(FileField)
URLField(Field)
BooleanField(Field)
NullBooleanField(BooleanField)

...还有很多字段,这里就不一一赘述了,具体详见官网:

代码语言:javascript
复制
https://docs.djangoproject.com/zh-hans/2.0/ref/forms/api/#django.forms.BoundField

多选字段

代码语言:javascript
复制
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,但是最终效果以插件为主!

代码语言:javascript
复制
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示例

代码语言:javascript
复制
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如何使用。

  • 首先GET请求时,返回页面。
  • POST请求时,验证数据,判断是否符合规则。
  • 如果失败返回错误信息,如果成功继续,写入数据库。

最后列举出常用的Form字段,还有如何使用多选字段。

如果在操作过程中有任务问题,记得下面留言,我们看到会第一时间解决问题。

态度决定高度,习惯主宰人生。如果觉得还不错,记得动手点赞以下哈。感谢你的观看。

想学习更多关于Python的知识,可以参考学习网址:http://pdcfighting.com/,点击阅读原文,可以直达噢~

------------------- End -------------------

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python爬虫与数据挖掘 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • Form组件的理解
    • 没有使用Form组件时
      • 使用Form组件时
        • 小总结
    • Form使用
    • Form字段
      • 常用字段
        • 多选字段
          • widget参数对应的插件
            • widget示例
            • 总结
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档