Django form&ModelForm

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django form&ModelForm相关的知识,希望对你有一定的参考价值。

 

django中的Form功能操作:

  • 验证用户请求

  • 生成html标签

    (保留上一次提交的数据)

比如用户注册信息验证:用户名不允许为空、密码最短6位,如果自己写需要些很多,比较麻烦,而Django form提供了特别便捷的实现方式

Form表单验证模板模板是一个类,创建如下:

1、初始form,创建form

 

技术分享
from django import forms
class FM(forms.Form):
    # 只关心处理自己定义的form表单数据,恶意攻击定义的数据不处理
    user = forms.CharField()
    pwd = forms.CharField()  # 这里的变量名必须和html form里的name保持一致
    email = forms.EmailField()

def fm(request):
    if request.method == "GET":
        return render(request, "fm.html")
    elif request.method == "POST":
        # 获取用户所有数据,每条数据请求的验证
        # 成功 --> 获取所有的正确信息;失败 --> 显示错误信息
        obj = FM(request.POST)
        r1 = obj.is_valid()
        if r1:  # 返回的正确信息
            print(obj.cleaned_data)
        else:   # 返回的错误信息
            print(obj.errors)
            print(obj.errors.as_json())
        return redirect(/fm/)
views.py

 

技术分享
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
    <form action="/fm/" method="POST">
        {% csrf_token %}
        <input type="text" name="user">
        <input type="text" name="pwd">
        <input type="text" name="email">
        <input type="submit" value="提交" />
    </form>
</body>
</html>
fm.html

 

 

<ul class="errorlist"><li>email<ul class="errorlist"><li>This field is required.</li></ul></li><li>pwd<ul class="errorlist"><li>This field is required.</li></ul></li><li>user<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
{"email": [{"message": "This field is required.", "code": "required"}], "pwd": [{"message": "This field is required.", "code": "required"}], "user": [{"message": "This field is required.", "code": "required"}]}

上面的错误信息为英文,能不能自定制呢?

2、自定制form错误信息,前端显示

技术分享
from django import forms
class FM(forms.Form):
    # 只关心处理自己定义的form表单数据,恶意攻击定义的数据不处理
    user = forms.CharField(error_messages={required:用户名不能为空})
    pwd = forms.CharField(
        max_length=12,
        min_length=6,
        error_messages={required:密码不能为空,min_length:密码长度不能小于6,max_length:密码长度不能大于12}
    )
    email = forms.EmailField(error_messages={required:用户名不能为空,invalid:邮箱格式错误})

def fm(request):
    if request.method == "GET":
        return render(request, "fm.html")
    elif request.method == "POST":
        obj = FM(request.POST)
        r1 = obj.is_valid()
        if r1:  # 返回的正确信息
            print(obj.cleaned_data)
        else:   # 返回的错误信息
            # ErrorDict
            # print(obj.errors[‘user‘][0])
            # print(obj.errors.as_json())
            return render(request,fm.html,{obj:obj})
        return render(request,fm.html)
views.py

 

 

技术分享
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
    <form action="/fm/" method="POST">
        {% csrf_token %}
        <p><input type="text" name="user"> {{ obj.errors.user.0 }}</p>
        <p><input type="text" name="pwd"> {{ obj.errors.pwd.0 }}</p>
        <p><input type="text" name="email"> {{ obj.errors.email.0 }}</p>
        <input type="submit" value="提交" />
    </form>
</body>
</html>
fm.html

 

 

3、保留上一次提交的数据,自动生成html标签

views里面不仅能帮我们生成错误信息,还能帮我们生成html标签。

技术分享
def fm(request):
    if request.method == "GET":
        obj = FM()  # 自动生成html时,get这里也需要创建对象
        return render(request, "fm.html",{obj:obj})
    elif request.method == "POST":
        obj = FM(request.POST)
        r1 = obj.is_valid()
        if r1:  # 返回的正确信息
            print(obj.cleaned_data)  # 这是个字典,注册直接下面那一句就成功了
            # models.UserInfo.objects.create(**obj.cleaned_data)
        else:   # 返回的错误信息
            return render(request,fm.html,{obj:obj})
        return render(request,fm.html)
views.py

 

 

技术分享
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
        <form action="/fm/" method="POST">
        {% csrf_token %}
        <p>{{ obj.user }} {{ obj.errors.user.0 }}</p>
        <p>{{ obj.pwd }} {{ obj.errors.pwd.0 }}</p>
        <p>{{ obj.email }} {{ obj.errors.email.0 }}</p>
        <input type="submit" value="提交" />
    </form>
</body>
</html>
fm.html

 

 

4、更简洁的html标签生成方法

这里生成虽然方便,但是可定制化不如上面高。

  • obj.as_p
  • obj.as_ul
  • obj.as_table

可以把上面html里的form改为:

 

    <form action="/fm/" method="POST">
        {% csrf_token %}
        {{ obj.as_p }}
        <input type="submit" value="提交" />
    </form>
    <form action="/fm/" method="POST">
        {% csrf_token %}
        {{ obj.as_ul }}
        <input type="submit" value="提交" />
    </form>
    <form action="/fm/" method="POST">
        {% csrf_token %}
        <table>
            {{ obj.as_table }}
        </table>  
        <input type="submit" value="提交" />
    </form>

 

 

 

 

5、自定义样式

form类里面的字段,只有一个功能,就是验证客户端发过来的数据。生成html的功能做不了。

但是怎么生成的html标签呢,在charfield里面有个插件,插件生成的。在其源码里做了html字符串的拼接返回。

 

from django import forms
from django.forms import widgets  # 插件在这里面
class FM(forms.Form):
    # 字段本身只做验证
    user = forms.CharField(         # 修改html标签,并指定样式##############
        error_messages={‘required‘:‘用户名不能为空‘},
        widget=widgets.Textarea(attrs={‘class‘:‘c1‘}),  # 页面再看就是textarea了
        label="用户名"
    )
    pwd = forms.CharField(
        max_length=12,
        min_length=6,
        error_messages={‘required‘:‘密码不能为空‘,‘min_length‘:‘密码长度不能小于6‘,‘max_length‘:‘密码长度不能大于12‘},
        widget=widgets.PasswordInput  # 密码密文显示,如果自定义样式也可加上(attrs……)
    )
    email = forms.EmailField(error_messages={‘required‘:‘用户名不能为空‘,‘invalid‘:‘邮箱格式错误‘})

  

而字段都在from django.forms import fields里面,所以上面的forms可以改用fields

email = fields.EmailField()

前端<p>{{ obj.user.label }}{{ obj.user }} {{ obj.errors.user.0 }}</p>

插件里面input、checkbox、select、redio等全部都有

6、form 内置字段

技术分享
Field
    required=True,               是否允许为空
    widget=None,                 HTML插件
    label=None,                  用于生成Label标签或显示内容
    initial=None,                初始值
    help_text=‘‘,                帮助信息(在标签旁边显示)
    error_messages=None,         错误信息 {required: 不能为空, invalid: 格式错误}
*   show_hidden_initial=False,   是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直)
*   validators=[],               自定义验证规则
    localize=False,              是否支持本地化,使用本地时间
    disabled=False,              是否可以编辑
    label_suffix=None            Label内容后缀

################# 下面的通过自己写正则表达式也能实现 ################# 
CharField(Field)
    max_length=None,             最大长度
    min_length=None,             最小长度
    strip=True                   是否移除用户输入空白

IntegerField(Field)
    max_value=None,              最大值
    min_value=None,              最小值

FloatField(IntegerField)
    ...

DecimalField(IntegerField)
    max_value=None,              最大值
    min_value=None,              最小值
    max_digits=None,             总长度
    decimal_places=None,         小数位长度

BaseTemporalField(Field)
    input_formats=None          时间格式化   

DateField(BaseTemporalField)    格式:2015-09-01
TimeField(BaseTemporalField)    格式:11:12
DateTimeField(BaseTemporalField)格式:2015-09-01 11:12

DurationField(Field)            时间间隔:%d %H:%M:%S.%f
    ...

RegexField(CharField)
    regex,                      自定制正则表达式
    max_length=None,            最大长度
    min_length=None,            最小长度
    error_message=None,         忽略,错误信息使用 error_messages={invalid: ...}

EmailField(CharField)      
    ...

FileField(Field)
    allow_empty_file=False     是否允许空文件

ImageField(FileField)      
    ...
    注:需要PIL模块,pip3 install Pillow
    以上两个字典使用时,需要注意两点:
        - form表单中 enctype="multipart/form-data"
        - view函数中 obj = MyForm(request.POST, request.FILES)

URLField(Field)
    ...


BooleanField(Field)  
    ...

NullBooleanField(BooleanField)
    ...

ChoiceField(Field)
    ...
    choices=(),                选项,如:choices = ((0,上海),(1,北京),)
    required=True,             是否必填
    widget=None,               插件,默认select插件
    label=None,                Label内容
    initial=None,              初始值
    help_text=‘‘,              帮助提示


ModelChoiceField(ChoiceField)
    ...                        django.forms.models.ModelChoiceField
    queryset,                  # 查询数据库中的数据
    empty_label="---------",   # 默认空显示内容
    to_field_name=None,        # HTML中value的值对应的字段
    limit_choices_to=None      # ModelForm中对queryset二次筛选

ModelMultipleChoiceField(ModelChoiceField)
    ...                        django.forms.models.ModelMultipleChoiceField



TypedChoiceField(ChoiceField)
    coerce = lambda val: val   对选中的值进行一次转换
    empty_value= ‘‘            空值的默认值

MultipleChoiceField(ChoiceField)
    ...

TypedMultipleChoiceField(MultipleChoiceField)
    coerce = lambda val: val   对选中的每一个值进行一次转换
    empty_value= ‘‘            空值的默认值

ComboField(Field)
    fields=()                  使用多个验证,如下:即验证最大长度20,又验证邮箱格式
                               fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])

MultiValueField(Field)
    PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用

SplitDateTimeField(MultiValueField)
    input_date_formats=None,   格式列表:[%Y--%m--%d, %m%d/%Y, %m/%d/%y]
    input_time_formats=None    格式列表:[%H:%M:%S, %H:%M:%S.%f, %H:%M]

FilePathField(ChoiceField)     文件选项,目录下文件显示在页面中
    path,                      文件夹路径
    match=None,                正则匹配
    recursive=False,           递归下面的文件夹
    allow_files=True,          允许文件
    allow_folders=False,       允许文件夹
    required=True,
    widget=None,
    label=None,
    initial=None,
    help_text=‘‘

GenericIPAddressField
    protocol=both,           both,ipv4,ipv6支持的IP格式
    unpack_ipv4=False          解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用

SlugField(CharField)           数字,字母,下划线,减号(连字符)
    ...

UUIDField(CharField)           uuid类型
View Code

说一下上面的ChoiceField,它主要做选项用的

    city = fields.ChoiceField(
        choices=[(0,‘上海‘),(1,‘广州‘)]
    )
    city2 = fields.MultipleChoiceField(
        choices=[(0,‘上海‘),(1,‘广州‘)]
    )

  常用选择插件

技术分享
# 单radio,值为字符串
# user = fields.CharField(
#     initial=2,
#     widget=widgets.Radioselect(choices=((1,‘上海‘),(2,‘北京‘),))
# )

# 单radio,值为字符串
# user = fields.ChoiceField(
#     choices=((1, ‘上海‘), (2, ‘北京‘),),
#     initial=2,
#     widget=widgets.RadioSelect
# )

# 单select,值为字符串
# user = fields.CharField(
#     initial=2,
#     widget=widgets.Select(choices=((1,‘上海‘),(2,‘北京‘),))
# )

# 单select,值为字符串
# user = fields.ChoiceField(
#     choices=((1, ‘上海‘), (2, ‘北京‘),),
#     initial=2,
#     widget=widgets.Select
# )

# 多选select,值为列表
# user = fields.MultipleChoiceField(
#     choices=((1,‘上海‘),(2,‘北京‘),),
#     initial=[1,],
#     widget=widgets.SelectMultiple
# )


# 单checkbox
# user = fields.CharField(
#     widget=widgets.CheckboxInput()
# )


# 多选checkbox,值为列表
# user = fields.MultipleChoiceField(
#     initial=[2, ],
#     choices=((1, ‘上海‘), (2, ‘北京‘),),
#     widget=widgets.CheckboxSelectMultiple
# )
View Code

 

Django内置插件: 

 

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

 

自定义
    -- 字段(校验)
    - 插件(生成HTML

 

 

 

7、初始化操作

在Web应用程序中开发编写功能时,时常用到获取数据库中的数据并将值初始化在HTML中的标签上。

 

def fm(request):
    if request.method == "GET":
        dic = {
            "user":‘r1‘,
            "pwd":‘123456‘,
            "email":‘[email protected]‘,
            "city":1,
            "city2":[1,2],
        }
        obj = FM(initial=dic)  # 初始化
        return render(request, "fm.html",{‘obj‘:obj})

  

 参考博客

 参考博客


以上是关于Django form&ModelForm的主要内容,如果未能解决你的问题,请参考以下文章

Django(Form,ModelForm)

Form和ModelForm

Django-Form组件-forms.ModelForm

Django基础十之Form和ModelForm组件

django form 和modelform

Django之ModelForm