zoukankan      html  css  js  c++  java
  • django学习之- Form

    参考:http://www.cnblogs.com/wupeiqi/articles/6144178.html
    FORM中的字段只对post上来的数据进行form验证,
    主要涉及:字段 和 插件
    字段:对用户请求数据的验证。
    插件:用于自动生成html。
    - 自定义:
    - 创建类
    - 定义字段(验证)
    - 插件(生成html)
    - 初始化操作
    实例:通过前端html和后台django,通过from实现一个简单的表单验证及多个功能的展示
    前端fm.html代码:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    {#功能:实现表单进行数据验证,并在验证未通过情况下,页面不进行刷新,只提示错误#}
    <form action="/fm" method="post">
        {% csrf_token %}
    {#    以下第一个user.label为FM表单user字段的label值,第二个obj.user为FM表单的user字段,最后的一个是FM表单的error_messages错误提醒#}
        {% csrf_token %}
        <p>
            {{ obj.user.label }}{{ obj.user }}{{ obj.errors.user.0 }}
        </p>
        <p>
            {{ obj.pwd.label }}{{ obj.pwd }}{{obj.errors.pwd.0 }}
        </p>
        <p>
            {{ obj.email.label }}{{ obj.email }}{{ obj.errors.email.0 }}
        </p>
        <p>
            {{ obj.f.label }}{{ obj.f }}{{ obj.errors.f.0 }}
        </p>
        <p>
    {#        这个提交的是选中的文件的路径#}
            {{ obj.p }}
        </p>
        <p>
    {#        choice下拉框选项#}
            {{ obj.cite }}
        </p>
        <p>
    {#        单选#}
            {{ obj.cite2 }}
        </p>
        <p>
            {{ obj.mcite }}
        </p>
        <input type="submit" value="提交" />
    </form>
    </body>
    </html>
    View Code

      后台代码

    from django import forms
    from django.forms import fields
    # widgets 插件可以定义html的标签和样式,fields表示字段
    from django.forms import widgets
    class FM(forms.Form):
        # 这里的各个字段,本身自己只做验证
        user = fields.CharField(
            error_messages={'required':'用户名不能为空'}, # 错误提醒
            widget = widgets.Textarea(attrs={'class':'c1','style':'background:#e2e3e4'}), # html标签和样式
            label = '用户名', # 标签
            #initial='admin',  # 定义初始值
            )
        pwd = fields.CharField(
            max_length=12,
            min_length=6,
            error_messages={'required':'密码不能为空','min_length':'密码最小长度6位','max_length':'密码最大长度为12位'},
            widget = widgets.PasswordInput(attrs={'style':'background:#e3e4e5'}),
            label = '密码',
        )
        email = fields.EmailField(
            error_messages={'required':'邮箱不可以为空','invalid':'邮箱格式不正确'},
            label = '邮箱',
        )
        f = fields.FileField(
            label='上传文件'
        )
        # 可以显示指定目录下所有的文件
        p = fields.FilePathField(
            path='d:/'
        )
        # 下拉框
        cite = fields.ChoiceField(
            choices=[(0,'bj'),(1,'sh'),(2,'sz')]
        )
        cite2 = fields.CharField(
        initial=2,
        widget=widgets.RadioSelect(choices=((0,'man'),(1,'girl')))
        )
        # 多选下拉框
        mcite = fields.MultipleChoiceField(
            choices=[(0,'bj'),(1,'sh'),(2,'sz')]
        )
    
    def fm(request):
        # GET将返回表单输入框
        if request.method == 'GET':
            # 从数据库提取数据,为字段生成默认值,注意必须为字典格式,健必须为FM的字段名
            dic = {
                'user':'r1',
                'pwd':'abc',
                'email':'test@test',
                'cite':1,
                'mcite':[1,2],
            }
            obj = FM(initial=dic) # 这里将dic作为参数传入,即可生成默认值
            return render(request,'fm.html',{'obj':obj})
        if request.method == 'POST':
            # POST获取所有提交的数据并进行校验(is_valid),cleaned_data以字典格式返回所有校验成功的数据,errors返回所有校验失败的数据,
            # 直接将obj返回给前端,前端进行错误打印,as_json以json格式打印所有错误
            obj = FM(request.POST)
            ck = obj.is_valid()
            if ck:
                print(obj.cleaned_data)
                # 将表单数据进行数据库添加
                models.UserName.objects.create(**obj.cleaned_data)
                return redirect('/fm')
            else:
                print(obj.errors)
                print(obj.errors.as_json())
                return render(request,'fm.html',{'obj':obj})
    View Code
    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, 小数位长度
    ### 时间格式验证###3
    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
    ...
    ### 这个就相当于 CharField + validators ####
    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)  # URL的正则表达式
    ...
    BooleanField(Field) # 布尔
    ...
    NullBooleanField(BooleanField)
    ...
    ### 比较重要######
    ChoiceField(Field) # 单选下拉框
    ...
    choices=(), 选项,如:choices = ((0,'上海'),(1,'北京'),)
    required=True, 是否必填
    widget=None, 插件,默认select插件
    label=None, Label内容
    initial=None, 初始值
    help_text='', 帮助提示
    MultipleChoiceField(ChoiceField) # 多选下拉框
    ...

    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= '' 空值的默认值



    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类型
    ##### 内置插件 ######
    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
    每个插件内部都可以使用attr自定制属性
    实例:通过表单实现单选
    forms.py 内容
    from django.forms import widgets,fields
    from django import forms
    from app01 import models
    from django.forms.models import ModelChoiceField,ModelMultipleChoiceField
    # ModelChoiceField 单选
    # ModelMultipleChoiceField 多选
    class UserInfoForm(forms.Form):
        user = fields.CharField(
            required=False,
            widget = widgets.Textarea(attrs={'class':'c1'})
        )
        pwd = fields.CharField(
            max_length=12,
            widget = widgets.PasswordInput(attrs={'class':'c1'})
        )
        user_type = fields.ChoiceField(
            # choices=[(0,'普通用户'),(1,'超级用户')],
            choices=[],
            widget=widgets.Select
        )
        user_type2 = fields.CharField(
            widget=widgets.Select(choices=[])
        )
        user_type3 = ModelChoiceField(
            empty_label='请选择用户类型',
            # 使用此方法虽然不用使用构造方法,但是表需要定制__str__方法
            queryset=models.UserType.objects.all(),
            to_field_name='id'  # 生成select标签内option的value值
        )
        def __init__(self,*args,**kwargs):
            super(UserInfoForm,self).__init__(*args,**kwargs)
            self.fields['user_type'].choices = models.UserType.objects.values_list('id','name')
            self.fields['user_type2'].widget.choices = models.UserType.objects.values_list('id','name')
    View Code
    views.py内容
    def index2(request):
        from app01.forms import UserInfoForm
        obj = UserInfoForm()
        return render(request,'indexform.html',{'obj':obj})
    indexform.html内容
    <body>
    <p>{{ obj.user }}</p>
    <p>{{ obj.pwd }}</p>
    <p>{{ obj.user_type }}</p>
    <p>{{ obj.user_type2 }}</p>
    <p>{{ obj.user_type3 }}</p>
    </body>

    form: 数据验证,经历3个阶段

        - 每一个字段(正则,字段钩子)
    - clean
    - _post_clean
    对于错误信息:整体的错误信息放于__all__内。
    实例:数据验证,使用钩子
    forms.py内容
    # 钩子举例,注册,登录
    from django.core.exceptions import ValidationError
    class RegisterForm(forms.Form):
        '''字段增加验证方式,首先进行user字段的正则表达式验证,如果通过了。然后进行源码里预留的钩子clean_user验证'''
        user = fields.CharField()
        email = fields.EmailField()
    
        def clean_user(self):
            '''源码里通过钩子clean+_field,增加正则表达式验证'''
            c = models.User.objects.filter(name=self.cleaned_data['user']).count()
            if not c:
                return self.cleaned_data['user']
            else:
                raise ValidationError('用户名已经存在',code='xxx')
        def clean_email(self):
            pass
    
    class LoginForm(forms.Form):
        user = fields.CharField()
        pwd = fields.CharField(validators=[])  # 这个参数可以自定义正则表达式验证
    
        def clean_user(self):
            '''第一类钩子字段验证,源码里通过钩子clean+_field,增加正则表达式验证'''
            c = models.User.objects.filter(name=self.cleaned_data['user']).count()
            if not c:
                return self.cleaned_data['user']
            else:
                raise ValidationError('用户名已经存在',code='xxx')
        def clean_pwd(self):
            pass
        def clean(self):
            '''第二类钩子 整体进行验证'''
            self.cleaned_data['user']
            self.cleaned_data['pwd']
            c = models.User.objects.filter(name=self.cleaned_data['user'],pwd=self.cleaned_data['pwd']).count()
            if c:
                return self.cleaned_data
            else:
                raise ValidationError('用户名或密码错误')
        def _post_clean(self):
            '''第三类钩子'''
            pass
    View Code

    views.py 内容

     def register(request):
        from app01.forms import RegisterForm
        obj = RegisterForm(request.POST)
        if obj.is_valid():
            obj.cleaned_data
        else:
            obj.errors
     

























  • 相关阅读:
    python
    mysql 操作
    you-get 使用代理
    恢复本地策略组--用于启动项管理等
    bat批处理——获取文件夹下所有文件名/重命名
    cmd--set用法,下次补充实例
    bat+7z批量压缩"文件夹"
    Excel提取字符串示例
    cron
    AIX修改用户密码登录不成功案例分享
  • 原文地址:https://www.cnblogs.com/zy6103/p/8030376.html
Copyright © 2011-2022 走看看