Django之Form组件

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

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

小试牛刀

1、创建Form类

from django.forms import Form
from django.forms import widgets
from django.forms import fields

class MyForm(Form):
    user = fields.CharField(
        widget=widgets.TextInput(attrs={‘id‘: ‘i1‘, ‘class‘: ‘c1‘})
    )

    gender = fields.ChoiceField(
        choices=((1, ‘男‘), (2, ‘女‘),),
        initial=2,
        widget=widgets.RadioSelect
    )

    city = fields.CharField(
        initial=2,
        widget=widgets.Select(choices=((1,‘上海‘),(2,‘北京‘),))
    )

    pwd = fields.CharField(
        widget=widgets.PasswordInput(attrs={‘class‘: ‘c1‘}, render_value=True)
    )

  

2、View函数处理

from django.shortcuts import render, redirect
from .forms import MyForm

def index(request):
    if request.method == "GET":
        obj = MyForm()
        return render(request, ‘index.html‘, {‘form‘: obj})
    elif request.method == "POST":
        obj = MyForm(request.POST, request.FILES)
        if obj.is_valid():
            values = obj.clean()
            print(values)
        else:
            errors = obj.errors
            print(errors)
        return render(request, ‘index.html‘, {‘form‘: obj})
    else:
        return redirect(‘http://www.google.com‘)

 

3、生成HTML


1

2

3

4

5

6

7

<form action="/" method="POST" enctype="multipart/form-data">

    <p>{{ form.user }} {{ form.user.errors }}</p>

    <p>{{ form.gender }} {{ form.gender.errors }}</p>

    <p>{{ form.city }} {{ form.city.errors }}</p>

    <p>{{ form.pwd }} {{ form.pwd.errors }}</p>

    <input type="submit"/>

</form> 

 <form method="POST" enctype="multipart/form-data">
        {% csrf_token %}

            {{ form.xxoo.label }}
            {{ form.xxoo.id_for_label }}
            {{ form.xxoo.label_tag }}
            {{ form.xxoo.errors }}
            <p>{{ form.user }} {{ form.user.errors }}</p>
            <input type="submit" />
    </form>

其他标签

Form类

创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML;

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

136

137

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)            时间间隔:%%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类型

    ...

注:UUID是根据MAC以及当前时间等创建的不重复的随机字符串

 >>> import uuid

    # make a UUID based on the host ID and current time
    >>> uuid.uuid1()    # doctest: +SKIP
    UUID(‘a8098c1a-f86e-11da-bd1a-00112444be1e‘)

    # make a UUID using an MD5 hash of a namespace UUID and a name
    >>> uuid.uuid3(uuid.NAMESPACE_DNS, ‘python.org‘)
    UUID(‘6fa459ea-ee8a-3ca4-894e-db77e160355e‘)

    # make a random UUID
    >>> uuid.uuid4()    # doctest: +SKIP
    UUID(‘16fd2706-8baf-433b-82eb-8c7fada847da‘)

    # make a UUID using a SHA-1 hash of a namespace UUID and a name
    >>> uuid.uuid5(uuid.NAMESPACE_DNS, ‘python.org‘)
    UUID(‘886313e1-3b8a-5372-9b90-0c9aee199e5d‘)

    # make a UUID from a string of hex digits (braces and hyphens ignored)
    >>> x = uuid.UUID(‘{00010203-0405-0607-0809-0a0b0c0d0e0f}‘)

    # convert a UUID to a string of hex digits in standard form
    >>> str(x)
    ‘00010203-0405-0607-0809-0a0b0c0d0e0f‘

    # get the raw 16 bytes of the UUID
    >>> x.bytes
    b‘\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f‘

    # make a UUID from a 16-byte string
    >>> uuid.UUID(bytes=x.bytes)
    UUID(‘00010203-0405-0607-0809-0a0b0c0d0e0f‘)

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

常用选择插件


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

# )

在使用选择标签时,需要注意choices的选项可以从数据库中获取,但是由于是静态字段 ***获取的值无法实时更新***,那么需要自定义构造方法从而达到此目的。

方式一:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

from django.forms import Form

from django.forms import widgets

from django.forms import fields

from django.core.validators import RegexValidator

class MyForm(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‘)

方式二:

使用django提供的ModelChoiceField和ModelMultipleChoiceField字段来实现


1

2

3

4

5

6

7

8

9

10

from django import forms

from django.forms import fields

from django.forms import widgets

from django.forms import models as form_model

from django.core.exceptions import ValidationError

from django.core.validators import RegexValidator

class FInfo(forms.Form):

    authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all())

    # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())

自定义验证规则

方式一:


1

2

3

4

5

6

7

8

9

from django.forms import Form

from django.forms import widgets

from django.forms import fields

from django.core.validators import RegexValidator

class MyForm(Form):

    user = fields.CharField(

        validators=[RegexValidator(r‘^[0-9]+$‘‘请输入数字‘), RegexValidator(r‘^159[0-9]+$‘‘数字必须以159开头‘)],

    )

方式二:


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

import re

from django.forms import Form

from django.forms import widgets

from django.forms import fields

from django.core.exceptions import ValidationError

# 自定义验证规则

def mobile_validate(value):

    mobile_re = re.compile(r‘^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$‘)

    if not mobile_re.match(value):

        raise ValidationError(‘手机号码格式错误‘)

class PublishForm(Form):

    title = fields.CharField(max_length=20,

                            min_length=5,

                            error_messages={‘required‘‘标题不能为空‘,

                                            ‘min_length‘‘标题最少为5个字符‘,

                                            ‘max_length‘‘标题最多为20个字符‘},

                            widget=widgets.TextInput(attrs={‘class‘"form-control",

                                                          ‘placeholder‘‘标题5-20个字符‘}))

    # 使用自定义验证规则

    phone = fields.CharField(validators=[mobile_validate, ],

                            error_messages={‘required‘‘手机不能为空‘},

                            widget=widgets.TextInput(attrs={‘class‘"form-control",

                                                          ‘placeholder‘: u‘手机号码‘}))

    email = fields.EmailField(required=False,

                            error_messages={‘required‘: u‘邮箱不能为空‘,‘invalid‘: u‘邮箱格式错误‘},

                            widget=widgets.TextInput(attrs={‘class‘"form-control"‘placeholder‘: u‘邮箱‘}))

方法三:自定义方法


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

from django import forms

    from django.forms import fields

    from django.forms import widgets

    from django.core.exceptions import ValidationError

    from django.core.validators import RegexValidator

    class FInfo(forms.Form):

        username = fields.CharField(max_length=5,

                                    validators=[RegexValidator(r‘^[0-9]+$‘‘Enter a valid extension.‘‘invalid‘)], )

        email = fields.EmailField()

        def clean_username(self):

            """

            Form中字段中定义的格式匹配完之后,执行此方法进行验证

            :return:

            """

            value = self.cleaned_data[‘username‘]

            if "666" in value:

                raise ValidationError(‘666已经被玩烂了...‘‘invalid‘)

            return value

方式四:同时生成多个标签进行验证


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

from django.forms import Form

from django.forms import widgets

from django.forms import fields

from django.core.validators import RegexValidator

############## 自定义字段 ##############

class PhoneField(fields.MultiValueField):

    def __init__(self*args, **kwargs):

        # Define one message for all fields.

        error_messages = {

            ‘incomplete‘‘Enter a country calling code and a phone number.‘,

        }

        # Or define a different message for each field.

        = (

            fields.CharField(

                error_messages={‘incomplete‘‘Enter a country calling code.‘},

                validators=[

                    RegexValidator(r‘^[0-9]+$‘‘Enter a valid country calling code.‘),

                ],

            ),

            fields.CharField(

                error_messages={‘incomplete‘‘Enter a phone number.‘},

                validators=[RegexValidator(r‘^[0-9]+$‘‘Enter a valid phone number.‘)],

            ),

            fields.CharField(

                validators=[RegexValidator(r‘^[0-9]+$‘‘Enter a valid extension.‘)],

                required=False,

            ),

        )

        super(PhoneField, self).__init__(error_messages=error_messages, fields=f, require_all_fields=False*args,

                                         **kwargs)

    def compress(self, data_list):

        """

        当用户验证都通过后,该值返回给用户

        :param data_list:

        :return:

        """

        return data_list

############## 自定义插件 ##############

class SplitPhoneWidget(widgets.MultiWidget):

    def __init__(self):

        ws = (

            widgets.TextInput(),

            widgets.TextInput(),

            widgets.TextInput(),

        )

        super(SplitPhoneWidget, self).__init__(ws)

    def decompress(self, value):

        """

        处理初始值,当初始值initial不是列表时,调用该方法

        :param value:

        :return:

        """

        if value:

            return value.split(‘,‘)

        return [NoneNoneNone]

初始化数据

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

1、Form

from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator

class MyForm(Form):
    user = fields.CharField()

    city = fields.ChoiceField(
        choices=((1, ‘上海‘), (2, ‘北京‘),),
        widget=widgets.Select
    )

  

2、Views


1

2

3

4

5

6

7

8

9

10

11

12

13

14

from django.shortcuts import render, redirect

from .forms import MyForm

def index(request):

    if request.method == "GET":

        values = {‘user‘‘root‘‘city‘2}

        obj = MyForm(values)

        return render(request, ‘index.html‘, {‘form‘: obj})

    elif request.method == "POST":

        return redirect(‘http://www.google.com‘)

    else:

        return redirect(‘http://www.google.com‘)

3、HTML


1

2

3

4

5

6

7

<form method="POST" enctype="multipart/form-data">

    {% csrf_token %}

    <p>{{ form.user }} {{ form.user.errors }}</p>

    <p>{{ form.city }} {{ form.city.errors }}</p>

    <input type="submit"/>

</form>

4.Django之ModelForm组件


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

ModelForm

    a.  class Meta:

            model,                           # 对应Model的

            fields=None,                     # 字段

            exclude=None,                    # 排除字段

            labels=None,                     # 提示信息

            help_texts=None,                 # 帮助提示信息

            widgets=None,                    # 自定义插件

            error_messages=None,             # 自定义错误信息(整体错误信息from django.core.exceptions import NON_FIELD_ERRORS)

            field_classes=None               # 自定义字段类 (也可以自定义字段)

            localized_fields=(‘birth_date‘,) # 本地化,如:根据不同时区显示数据

            如:

                数据库中

                    2016-12-27 04:10:57

                setting中的配置

                    TIME_ZONE = ‘Asia/Shanghai‘

                    USE_TZ = True

                则显示:

                    2016-12-27 12:10:57

    b. 验证执行过程

        is_valid -> full_clean -> 钩子 -> 整体错误

    c. 字典字段验证

        def clean_字段名(self):

            # 可以抛出异常

            # from django.core.exceptions import ValidationError

            return "新值"

    d. 用于验证

        model_form_obj = XXOOModelForm()

        model_form_obj.is_valid()

        model_form_obj.errors.as_json()

        model_form_obj.clean()

        model_form_obj.cleaned_data

    e. 用于创建

        model_form_obj = XXOOModelForm(request.POST)

        #### 页面显示,并提交 #####

        # 默认保存多对多

            obj = form.save(commit=True)

        # 不做任何操作,内部定义 save_m2m(用于保存多对多)

            obj = form.save(commit=False)

            obj.save()      # 保存单表信息

            obj.save_m2m()  # 保存关联多对多信息

    f. 用于更新和初始化

        obj = model.tb.objects.get(id=1)

        model_form_obj = XXOOModelForm(request.POST,instance=obj)

        ...

        PS: 单纯初始化

            model_form_obj = XXOOModelForm(initial={...})

时间: 2024-07-30 15:48:08

Django之Form组件的相关文章

Python之路【第二十一篇】:Django之Form组件

Django之Form组件 Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 小试牛刀 1.创建Form类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 from django.forms import Form from django.forms import widgets from django.forms imp

【Django】Form组件

目录 Form组件介绍 常用字段与插件 Form组件中所有内置字段 从数据库中获取数据 校验示例 检验手机号是否合法 方式一(基本操作) 方式二(自定义验证规则) 方式三(利用钩子) 验证密码一致性 钩子 局部钩子 全局钩子 进阶 批量添加样式 ModelForm Form套Form @ *** Form组件介绍 在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,

django之form组件、cookie、session

django之form组件.cookie.session django form组件 1.渲染标签 2.校验数据 3.展示信息 校验数据 # 第一步需要一个form类 from django import forms class MyForm(forms.Form): name = forms.CharField(max_length=8) password = forms.CharField(max_length=8,min_length=3) email = forms.EmailField

[oldboy-django][2深入django]初始Form组件

http://www.cnblogs.com/wupeiqi/articles/6144178.html 1 初始Form组件 # Form验证(初始Form组件验证) - 问题: - 无法记住上次提交的内容,页面刷新数据消失 - 重复进行提交数据的校验(数据是否为空,长度大小等等) - 解决方法:django Form组件 - 定义规则(数据的格式,字段必须和表单上name属性一致) class LoginForm(Form): 实例化对象obj = LoginForm(request.POS

Django中Form组件拾遗(比较坑爹的地方+易忽略的点)

[001]Form组件之自动渲染一个ID选择器 在前面的章节中,我们使用了Django自带的Form组件帮我们完成对表单数据的校验,借助于Form组件,它帮我们自动渲染出input输入框,之前没怎么注意这块,最近才发现 它帮我们渲染出的input输入框自带了id选择器,来看如下的截图就明白了,这个地方坑了很久: <input class="form-control" id="id_email" name="email" placeholde

Python学习(三十九)—— Django之Form组件

一.构建一个表单 假设你想在你的网站上创建一个简单的表单,以获得用户的名字.你需要类似这样的模板: <form action="/your-name/" method="post"> <label for="your_name">Your name: </label> <input id="your_name" type="text" name="your

Django框架-Form组件

一.DjangoForm组件介绍 我们之前在html页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如验证用户是否输入,输入的长度和格式等是否正确,如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息. Django Form组件就实现了上面所述的功能. 1.生成页面可用的html标签(生成input框) 2.对用户提交的数据进行校验 3.错误信息的展示 4.保留上次的输入 缺

Django的form组件应用登陆或者注册

from django import forms from django.forms import Form from django.forms import widgets from django.forms import fields from django.core.exceptions import ValidationError from blog.models import * class RegisterForm(Form): # 自定义form组件 username = fiel

Django中Form组件的使用

Form介绍 HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确.如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.. Django form组件就实现了上面所述的功能. 总结一下,其实form组件的主要功能如下: 生成页面可用的HTML标签 对用户提交的数据进行校验 保留上次输入内容 普通方式手写注册功能 views.p