zoukankan      html  css  js  c++  java
  • Django 组建 forms

    一、校验字段功能

      通过注册用户这个实例来学习校验字段功能。

    1、模型:models.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from django.db import models
     
    # Create your models here.
     
    class UserInfo(models.Model):
        name = models.CharField(max_length=32)
        pwd = models.CharField(max_length=32)
        email = models.EmailField()
        tel = models.CharField(max_length=32)

      修改配置后,完成数据库迁移操作,可以查看到UserInfo表已经创建完成。

    2、模板:reg.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="" method="post">
        {% csrf_token %}
        <p>用户名<input type="text" name="name"></p>
        <p>密码<input type="text" name="pwd"></p>
        <p>确认密码<input type="text" name="r_pwd"></p>
        <p>邮箱<input type="text" name="email"></p>
        <p>手机号<input type="text" name="tel"></p>
        <input type="submit">
    </form>
    </body>
    </html>

    3、视图函数:views.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    from django.shortcuts import render,HttpResponse
    # Create your views here.
    from django import forms   # 引入forms组件
     
    class UserForm(forms.Form):   # 必须继承forms.Form
        name = forms.CharField(min_length=4)
        pwd = forms.CharField(min_length=4)
        r_pwd = forms.CharField(min_length=4)
        email = forms.EmailField()
        tel = forms.CharField()
     
    def reg(request):
        if request.method=="POST":
            print(request.POST)
            # 生成forms对象后,传入字典就可以做一个个值的校验
            # form = UserForm({"name": "yuan", "email": "123@qq.com", "xxx":"alex"})
            form = UserForm(request.POST)   # form表单的name属性值应该与forms组件的字段名称一致,不一致的键值不会去做校验
            print(form.is_valid())     # 返回True/False
            # 帮忙校验
            if form.is_valid():  # 注意:form.is_valid是帮忙校验返回布尔值的,true或false(所有都通过才返回true)
                # 类定义的字段均符合要求,返回true,有多的字段直接忽略
                print(form.cleaned_data)   # {'name': 'yuan', 'pwd': '1234', 'r_pwd': '1234', 'email': '1234@163.com', 'tel': '123123'}
            else:
                # 有正确也有错误信息也是返回false
                print(form.cleaned_data)   # 字段值符合要求的放在cleaned_data    {'name': 'yuan', 'pwd': '123456', 'tel': '123123'}
                print(form.errors)         # 字段不符合要求的对应的键作为键,错误信息作为值   <ul class="errorlist"><li>r_pwd<ul class="errorlist">...
                print(type(form.errors))   # <class 'django.forms.utils.ErrorDict'>  还是一个字段类型
                print(form.errors.get("r_pwd"))     # <ul class="errorlist"><li>This field is required.</li></ul>
                print(type(form.errors.get("r_pwd")))    # <class 'django.forms.utils.ErrorList'> 用列表存放错误信息
                print(form.errors.get("r_pwd")[0])   # 获取到报错信息:This field is required.
            """
            form.is_valid()  校验返回布尔值
            if 所有的字段校验成功,则form.cleaned_data:{"name": "yuan", "email": "123@qq.com"}
            如果校验失败,则form.errors放入所有错误的字段。
            """
            return HttpResponse("OK")
        return render(request, "reg.html")

    注意:

    (1)引入forms组件,定义的类必须继承forms.Form,forms类定义过的属性默认非空。

    1
    2
    3
    4
    5
    6
    7
    8
    from django import forms   # 引入forms组件
     
    class UserForm(forms.Form):   # 必须继承forms.Form
        name = forms.CharField(min_length=4)
        pwd = forms.CharField(min_length=4)
        r_pwd = forms.CharField(min_length=4)
        email = forms.EmailField()
        tel = forms.CharField()

    (2)生成forms对象,需要注意的是给对象传入字典就可以做一个个值的校验:

    1
    form = UserForm({"name": "yuan", "email": "123@qq.com", "xxx":"alex"})

      但是我们需要的是form表单属性与forms组件字段的校验,因此需要把request.POST传入forms对象:

    1
    form = UserForm(request.POST) 

      form表单的name属性值应该与forms组件的字段名称一致,不一致的键值不会去做校验。

    (3)form.is_valid() :做校验返回布尔值的,所有都通过才返回True,否则返回False。与forms组件字段无关的键值不影响返回结果。

    1
    2
    3
    4
    5
    6
    7
    if form.is_valid():  # 注意:form.is_valid是帮忙校验返回布尔值的,true或false(所有都通过才返回true)
        # 类定义的字段均符合要求,返回true,有多的字段直接忽略
        print(form.cleaned_data)   # {'name': 'yuan', 'pwd': '1234', 'r_pwd': '1234', 'email': '1234@163.com', 'tel': '123123'}
    else:
        # 有正确也有错误信息也是返回false
        print(form.cleaned_data)   # 字段值符合要求的放在cleaned_data    {'name': 'yuan', 'pwd': '123456', 'tel': '123123'}
        print(form.errors)         # 字段不符合要求的对应的键作为键,错误信息作为值   <ul class="errorlist"><li>r_pwd<ul class="errorlist">...

    (4)form.cleaned_data:字段值符合要求的放在cleaned_data中。字典数据类型。

    (5)form.errors:字段不符合要求的对应的键作为键,错误信息作为值。虽然返回结果比较复杂,但依然是字典数据类型,可以通过form.errors.get(“不符合的键”)来拿到键值,键值为列表数据类型。因此可以通过form.errors.get("不符合键")[0]拿到错误信息。

    二、渲染标签功能

    1、渲染方式一:

    视图函数:将forms空对象传给模板

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    from django import forms   # 引入forms组件
     
    class UserForm(forms.Form):   # 必须继承forms.Form
        # forms.CharField和forms.EmailField会渲染为input标签
        name = forms.CharField(min_length=4)    # 默认label是字段名
        pwd = forms.CharField(min_length=4, label="密码")   # 如果需要中文label可以手动设置
        r_pwd = forms.CharField(min_length=4, label="确认密码")
        email = forms.EmailField(label="邮箱")
        tel = forms.CharField(label="手机")
     
    def reg(request):
        form = UserForm()
        return render(request, "reg.html", locals())

    模板:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <h3>form组件渲染方式1</h3>
    <form action="" method="post">
        {% csrf_token %}
        <p>{{ form.name.label }}
            {{ form.name }}
        </p>
        <p>{{ form.pwd.label }}
            {{ form.pwd }}
        </p>
        <p>{{ form.r_pwd.label }}
            {{ form.r_pwd }}
        </p>
        <p>{{ form.email.label }}
            {{ form.email }}
        </p>
        <p>{{ form.tel.label }}
            {{ form.tel }}
        </p>
        <input type="submit">
    </form>

    渲染效果:

      

    2、渲染方式二

      其他与方式一同理,但是用for循环获取forms对象内字段。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <h3>forms组件渲染方式2</h3>
    <form action="" method="post">
        {% csrf_token %}
        {% for field in form %}
            <p>
                <label for="">{{ field.label }}</label>
                {{ field }}
            </p>
        {% endfor %}
        <input type="submit">
    </form>

      渲染效果:

      

    3、渲染方式三

      调用form对象的组件:as_p,即完成渲染。缺点是结构固定。(还有一种是as_ul)

    1
    2
    3
    4
    5
    6
    <hr>
    <h3>forms组件渲染方式3</h3>
    <form action="" method="post">
        {% csrf_token %}
        {{ form.as_p }}
    </form>

      渲染效果:

      

    三、显示错误与重置输入信息功能

    1、视图

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    def reg(request):
        if request.method=="POST":
            form = UserForm(request.POST)   # 绑定数据的form表单
            print(form.is_valid())     # 返回True/False
            if form.is_valid():
                # 类定义的字段均符合要求,返回true,有多的字段直接忽略
                print(form.cleaned_data)     #所有干净字段及对应的值
            else:
                # 有正确也有错误信息也是返回false
                print(form.cleaned_data)
                # print(form.errors)                 # ErrorDict : {"校验错误的字段":["错误信息",]}     
                # print(form.errors.get("name"))     # ErrorList ["错误信息",]
            return render(request, "reg.html", locals())
     
        form = UserForm()   # 未绑定数据的form表单
        return render(request, "reg.html", locals())

    2、模板

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <h3>显示错误与重置输入信息</h3>
    <form action="" method="post">
        {% csrf_token %}
        <p>{{ form.name.label }}
            {{ form.name }} <span>{{ form.name.errors.0 }}</span>
        </p>
        <p>{{ form.pwd.label }}
            {{ form.pwd }} <span>{{ form.pwd.errors.0 }}</span>
        </p>
        <p>{{ form.r_pwd.label }}
            {{ form.r_pwd }} <span>{{ form.r_pwd.errors.0 }}</span>
        </p>
        <p>{{ form.email.label }}
            {{ form.email }} <span>{{ form.email.errors.0 }}</span>
        </p>
        <p>{{ form.tel.label }}
            {{ form.tel }} <span>{{ form.tel.errors.0 }}</span>
        </p>
        <input type="submit">
    </form>

    四、forms组件的参数配置

      上面完成的注册页面,显示效果比较糟糕。因此需要引入widgets模块来调整组件参数配置,优化小时效果。

    1、reg.html引入样式

      模板引入bootstrap,并仅保留渲染方式一生成的注册登录页面。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <head>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
    </head>
     
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-lg-offset-3">
                <hr>
                <h3>form组件渲染方式1</h3>
                <form action="" method="post">
                    {% csrf_token %}
                    <p>{{ form.name.label }}
                        {{ form.name }} <span>{{ form.name.errors.0 }}</span>
                    </p>
                    <p>{{ form.pwd.label }}
                        {{ form.pwd }} <span>{{ form.pwd.errors.0 }}</span>
                    </p>
                    <p>{{ form.r_pwd.label }}
                        {{ form.r_pwd }} <span>{{ form.r_pwd.errors.0 }}</span>
                    </p>
                    <p>{{ form.email.label }}
                        {{ form.email }} <span>{{ form.email.errors.0 }}</span>
                    </p>
                    <p>{{ form.tel.label }}
                        {{ form.tel }} <span>{{ form.tel.errors.0 }}</span>
                    </p>
                    <input type="submit">
                </form>

    2、在视图层引入widgets模块,配置修改forms类参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    from django.shortcuts import render,HttpResponse
    # Create your views here.
    from django import forms   # 引入forms组件
    from django.forms import widgets
     
    class UserForm(forms.Form):   # 必须继承forms.Form
        # forms.CharField和forms.EmailField会渲染为input标签
        name = forms.CharField(min_length=4, label="用户名", error_messages={"requried": "该字段不能为空"},
                               widget=widgets.TextInput(attrs={"class": "form-control"})
                               )
        pwd = forms.CharField(min_length=4, label="密码",   # 如果需要中文label可以手动设置
                              widget=widgets.PasswordInput(attrs={"class": "form-control"})  # 生成密文文本输入框
                              )
        r_pwd = forms.CharField(min_length=4, label="确认密码",
                                widget=widgets.TextInput(attrs={"class": "form-control"}))
        email = forms.EmailField(label="邮箱", error_messages={"requried": "该字段不能为空", "invalid": "格式错误"},
                                 widget=widgets.EmailInput(attrs={"class": "form-control"})
                                 # invalid修改格式错误提示
        tel = forms.CharField(label="手机",error_messages={"requried": "该字段不能为空"},
                              widget=widgets.TextInput(attrs={"class": "form-control"})

    注意:

      (1)在字段构造参数中设置"error_messages"修改字段错误提示消息:其中"requried"负责字段不能为空消息提示;"invalid"负责格式错误消息提示等。

      (2)在字段构造函数中配置input类型:设置为文本域、密码域、单选框、复选框等等类型。

    1
    2
    3
    widget=widgets.TextInput()
    widget=widgets.PasswordInput()
    widget=widgets.EmailInput()

      (2)给字段构造函数中配置修改属性。比如给type="text"的input标签设置bootstrap样式,给input标签添加类"form-control"。

    显示效果:

      

    五、局部钩子和全局钩子

      为了将代码解耦可以选择自己创建一个文件比如app01/myform.py存放钩子。

    1、myform.py:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    # forms组件
    from django.forms import widgets
     
    wid_01=widgets.TextInput(attrs={"class":"form-control"})
    wid_02=widgets.PasswordInput(attrs={"class":"form-control"})
     
    from django.core.exceptions import ValidationError
    class UserForm(forms.Form):
        name=forms.CharField(max_length=32,
                             widget=wid_01
                             )
        pwd=forms.CharField(max_length=32,widget=wid_02)
        r_pwd=forms.CharField(max_length=32,widget=wid_02)
        email=forms.EmailField(widget=wid_01)
        tel=forms.CharField(max_length=32,widget=wid_01)
     
     
        # 局部钩子
        def clean_name(self):
            val=self.cleaned_data.get("name")
            if not val.isdigit():
                return val
            else:
                raise ValidationError("用户名不能是纯数字!")
     
        # 全局钩子
        def clean(self):
            pwd=self.cleaned_data.get("pwd")
            r_pwd=self.cleaned_data.get("r_pwd")
     
            if pwd==r_pwd:
                return self.cleaned_data
            else:
                raise ValidationError('两次密码不一致!')

    views.py:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    from django.shortcuts import render,HttpResponse
    # Create your views here.
    from app01.myforms import *
     
    def reg(request):
        if request.method=="POST":
            form = UserForm(request.POST)   # 绑定数据的form表单
            if form.is_valid():
                # 类定义的字段均符合要求,返回true,有多的字段直接忽略
                print(form.cleaned_data)
            else:
                print(form.cleaned_data)   # 字段值符合要求的放在cleaned_data    {'name': 'yuan', 'pwd': '123456', 'tel': '123123'}
     
                # 全局钩子错误
                # print("error", form.errors.get("__all__")[0])
                errors = form.errors.get("__all__")
     
                return render(request, "reg.html", locals())
     
        form = UserForm()   # 未绑定数据的form表单
        return render(request, "reg.html", locals())

    reg.html:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <form action="" method="post" novalidate>
                {% csrf_token %}
     
                {% for field in form %}
                    <div>
                        <label for="">{{ field.label }}</label>
                        {{ field }}
                        <span class="pull-right" style="color: red">
                              {% if field.label == 'R pwd' %}
                              <span>{{ clean_error.0 }}</span>
                              {% endif %}
                              {{ field.errors.0 }}
                        </span>
                    </div>
                {% endfor %}
                <input type="submit" class="btn btn-default">
     
    </form>

    六、Forms组件归类及补充

    Django的Form主要具有一下几大功能:

    • 生成HTML标签
    • 验证用户数据(显示错误信息)
    • HTML Form提交保留上次提交数据
    • 初始化页面显示内容

    1、Django内置字段:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    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类型

    2、Django内置插件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    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

    3、常用选择插件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    # 单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
    # )
  • 相关阅读:
    inner join ,left join ,right join 以及java时间转换
    华为机试-整形数组合并
    华为机试-公共字串计算
    两个字符串的最长公共子序列的长度
    华为机试-字符串通配符
    工作中总结的编程小技巧
    C语言高效编程的几招(绝对实用,绝对经典)
    Java float保留两位小数或多位小数
    新浪云、阿里云、百度云、谷歌云、亚马逊云
    java经典40+分析
  • 原文地址:https://www.cnblogs.com/qinghe123/p/11276678.html
Copyright © 2011-2022 走看看