django Form基础(一)

一、Forms模块使用:

1.入门

1.前端模板
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <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>
    传统方式的表单
    ----->
<!------  建议是在用这种方式,定制更灵活
    <form action="/fm/" method="POST">
        <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>
    ----->
    <form action="/fm/" method="POST">
        {{ obj.as_p }}   #建议用这个
        #或
        {{ obj.as_ul }}
        #或
        <table>
            {{ obj.as_table }}
        </table>
        <input type="submit" value="提交">
    </form>

</body>
</html>
2.views文件
from django.shortcuts import render,redirect
from django import forms
from django.forms import fields
from app01 import models

class FM(forms.Form):
#field字段本身负责验证,widgit负责html样式 user
=forms.CharField(
              error_messages={'required':'用户名不能为空'}
              
widget= widgets.Textarea(attrs={'class':'c1','root':'id'})
              label = "密码"
                       #class为添加的类属性,root为自定义属性
              ) #{
"email": [{"message": "This field is required.", "code": "required"}], "user": [{"message": "This field is required.", "code": "required"}], "pwd": [{"message": "This field is required.", "code": "required"}]} #已code为键,输入相关的值 pwd=forms.CharField( max_length=12, min_length=6, error_messages={'required':'密码不能为空','min_length':'最小长度为6','max_length':'最大长度为12'}
    
widget = widgets.PasswordInput #如果要定制样式属性,需要在后面加括号,如:
                                       #widget = widgets.PasswordInput(attrs={'class':'c2'})
                                       #widget 中有如:radio,choice,input等标签
     ) 
email
=forms.EmailField(error_messages={'required':'邮箱不能为空','invalid':"邮箱格式错误"}) #前端的name值必须和本类中的变量名相同
def fm(request):
if request.method == "GET": obj = FM() #必须要写,否则看不到相关项
return render(request,'fm.html',{'obj':obj})
elif request.method
=="POST":
#获取用户所有数据 #每条数据请求的验证 #成功:获取所有的正确的信息 #失败:显示错误信息

obj
= FM(request.POST) r1=obj.is_valid() #验证是否成功
print(r1)
if r1:
   print(obj.cleaned_data)
#获取的所有正确信息{
'email': 'dfdf@163.com', 'user': 'dfdf', 'pwd': 'dfdf'}
models.UserInfo.objects.create(
**obj.cleaned_data) #用户注册功能完成
return redirect('/fm/')
else:
print(obj.errors)
#不加as_json(),显示中文 返回内容:
#"<ul class="errorlist">
#<li>pwd<ul class="errorlist">
# <li>用户名不能为空</li>
#</ul>
#</li>
#<li>email<ul class="errorlist">
   #<li>邮箱不能为空</li>
# </ul>
#</li>
#<li>user<ul class="errorlist">
#<li>用户名不能为空</li>
#</ul>
#</li>
#</ul>"
#所有都不输入,返回为:
#{"user": [{"message": "This field is required.", "code": "required"}],
# "email": [{"message": "This field is required.", "code": "required"}],
#"pwd": [{"message": "This field is required.", "code": "required"
}]}
print(obj.errors[
'user'])
#返回内容:"<ul class="errorlist"><li>用户名不能为空</li></ul>"
#获取相关字段的错误信息:

print(obj.errors[
'user'][0])
#返回内容:"用户名不能为空"
#获取错误信息中的第几个,错误信息格式:
{"email":[{"code":"required","message":"\u"}]}
return render(request,'fm.html',{'obj':obj})
return render(request, 'fm.html')
   city1 = fields.ChoiceField(
choices=[(0,'上海'),(1,'广州'),(2,'东莞')]
)#单选
city2 = fields.MultipleChoiceField(
choices=[(0, '上海'), (1, '广州'), (2, '东莞')]
)#多选
 
def fm(request):
if request.method == "GET":
obj = FM() #必须要写,否则看不到相关项
#初始化操作
dic = {
"user":'zhangsan',
"pwd":'123',
"email":'dfc@163.com',
"city1":1,
"city2":[1,2]
}
#obj = FM(initial=dic)
return render(request,'fm.html',{'obj':obj})
elif request.method=="POST":
#获取用户所有数据
#每条数据请求的验证
#成功:获取所有的正确的信息
#失败:显示错误信息
obj = FM(request.POST)
r1=obj.is_valid() #验证是否成功
print(r1)
if r1:
print(obj.cleaned_data)
#获取的所有正确信息{'email': 'dfdf@163.com', 'user': 'dfdf', 'pwd': 'dfdf'}
models.UserInfo.objects.create(**obj.cleaned_data)
#用户注册功能完成
return redirect('/fm/')
else:
#print(obj.errors)#不加as_json(),显示中文 返回内容:"<ul class="errorlist"><li>pwd<ul class="errorlist"><li>用户名不能为空</li></ul></li><li>email<ul class="errorlist"><li>邮箱不能为空</li></ul></li><li>user<ul class="errorlist"><li>用户名不能为空</li></ul></li></ul>"
#所有都不输入,返回为:{"user": [{"message": "This field is required.", "code": "required"}], "email": [{"message": "This field is required.", "code": "required"}], "pwd": [{"message": "This field is required.", "code": "required"}]}
#print(obj.errors['user']) #返回内容:"<ul class="errorlist"><li>用户名不能为空</li></ul>"
#获取相关字段的错误信息:
#print(obj.errors['user'][0]) #返回内容:"用户名不能为空"
#获取错误信息中的第几个,错误信息格式:{"email":[{"code":"required","message":"\u"}]}

return render(request,'fm.html',{'obj':obj})
return render(request, 'fm.html')


3.url文件 from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index), url(r'^fm/', views.fm), ]

 2.Django内置的所有字段

  1 Field    #所有字段的基类
  2     required=True,               是否允许为空
  3     widget=None,                 HTML插件
  4     label=None,                  用于生成Label标签或显示内容
  5     initial=None,                初始值
  6     help_text='',                帮助信息(在标签旁边显示)
  7     error_messages=None,         错误信息 {'required': '不能为空', 'invalid': '格式错误'}
  8     show_hidden_initial=False,   是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直  9     validators=[],               自定义验证规则
 10     localize=False,              是否支持本地化
 11     disabled=False,              是否可以编辑
 12     label_suffix=None            Label内容后缀
 13 
 14 CharField(Field)
 15     max_length=None,             最大长度
 16     min_length=None,             最小长度
 17     strip=True                   是否移除用户输入空白
 18 
 19 IntegerField(Field)
 20     max_value=None,              最大值
 21     min_value=None,              最小值
 22 
 23 FloatField(IntegerField)
 24     ...
 25 
 26 DecimalField(IntegerField)
 27     max_value=None,              最大值
 28     min_value=None,              最小值
 29     max_digits=None,             总长度
 30     decimal_places=None,         小数位长度
 31 
 32 DateField(BaseTemporalField)    格式:2015-09-01
 33 TimeField(BaseTemporalField)    格式:11:12
 34 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12
 35 
 36 DurationField(Field)            时间间隔:%d %H:%M:%S.%f
 37     ...
 38 
 39 RegexField(CharField)
 40     regex,                      自定制正则表达式
 41     max_length=None,            最大长度
 42     min_length=None,            最小长度
 43     error_message=None,         忽略,错误信息使用 error_messages={'invalid': '...'}
 44 
 45 EmailField(CharField)      
 46     ...
 47 
 48 FileField(Field)
 49     allow_empty_file=False     是否允许空文件
 50 
 51 ImageField(FileField)      
 52     ...
 53     注:需要PIL模块,pip3 install Pillow
 54     以上两个字典使用时,需要注意两点:
 55         - form表单中 enctype="multipart/form-data"
 56         - view函数中 obj = MyForm(request.POST, request.FILES)
 57 
 58 URLField(Field)
 59     ...
 60 
 61 BooleanField(Field)  
 62     ...
 63 
 64 NullBooleanField(BooleanField)
 65     ...
 66 
 67 ChoiceField(Field)
 68     ...
 69     choices=(),                选项,如:choices = ((0,'上海'),(1,'北京'),)
 70     required=True,             是否必填
 71     widget=None,               插件,默认select插件
 72     label=None,                Label内容
 73     initial=None,              初始值
 74     help_text='',              帮助提示
 75 
 76 
 77 ModelChoiceField(ChoiceField)
 78     ...                        django.forms.models.ModelChoiceField
 79     queryset,                  # 查询数据库中的数据
 80     empty_label="---------",   # 默认空显示内容
 81     to_field_name=None,        # HTML中value的值对应的字段
 82     limit_choices_to=None      # ModelForm中对queryset二次筛选
 83 
 84 
 85 ModelMultipleChoiceField(ModelChoiceField)
 86     ...                  django.forms.models.ModelMultipleChoiceField
 87 
 88 
 89 TypedChoiceField(ChoiceField)
 90     coerce = lambda val: val   对选中的值进行一次转换
 91     empty_value= ''            空值的默认值
 92 
 93 MultipleChoiceField(ChoiceField)
 94     ...
 95 
 96 TypedMultipleChoiceField(MultipleChoiceField)
 97     coerce = lambda val: val   对选中的每一个值进行一次转换
 98     empty_value= ''            空值的默认值
 99 
100 
101 ComboField(Field)
102     fields=()                  使用多个验证,如下:即验证最大长度20,又验证邮箱格式
103                                fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])
104 
105 
106 MultiValueField(Field)
107     PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用
108 
109 
110 SplitDateTimeField(MultiValueField)
111     input_date_formats=None,   格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y']
112     input_time_formats=None    格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']
113 
114 
115 
116 FilePathField(ChoiceField)     文件选项,目录下文件显示在页面中
117     path,                      文件夹路径
118     match=None,                正则匹配
119     recursive=False,           递归下面的文件夹
120     allow_files=True,          允许文件
121     allow_folders=False,       允许文件夹
122     required=True,
123     widget=None,
124     label=None,
125     initial=None,
126     help_text=''
127 
128 
129 
130 GenericIPAddressField
131     protocol='both',           both,ipv4,ipv6支持的IP格式
132     unpack_ipv4=False          解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用
133 
134 SlugField(CharField)           数字,字母,下划线,减号(连字符)
135     ...
136 
137 
138 UUIDField(CharField)           uuid类型
139     ...
140  

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

 # 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')

常用插件

 1 # 单radio,值为字符串
 2 # user = fields.CharField(
 3 #     initial=2,
 4 #     widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))
 5 # )
 6  
 7 # 单radio,值为字符串
 8 # user = fields.ChoiceField(
 9 #     choices=((1, '上海'), (2, '北京'),),
10 #     initial=2,
11 #     widget=widgets.RadioSelect
12 # )
13  
14 # 单select,值为字符串
15 # user = fields.CharField(
16 #     initial=2,
17 #     widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))
18 # )
19  
20 # 单select,值为字符串
21 # user = fields.ChoiceField(
22 #     choices=((1, '上海'), (2, '北京'),),
23 #     initial=2,
24 #     widget=widgets.Select
25 # )
26  
27 # 多选select,值为列表
28 # user = fields.MultipleChoiceField(
29 #     choices=((1,'上海'),(2,'北京'),),
30 #     initial=[1,],
31 #     widget=widgets.SelectMultiple
32 # )
33  
34  
35 # 单checkbox
36 # user = fields.CharField(
37 #     widget=widgets.CheckboxInput()
38 # )
39  
40  
41 # 多选checkbox,值为列表
42 # user = fields.MultipleChoiceField(
43 #     initial=[2, ],
44 #     choices=((1, '上海'), (2, '北京'),),
45 #     widget=widgets.CheckboxSelectMultiple
46 # )

 

 

3.自定义验证规则

方法一:
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开头')], )
方法二:
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'邮箱'}))
方法三:
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


方法四:同时生成多个标签进行验证
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]

初始化操作:

 

 

 

1.基本使用

 1 ===1.forms.py文件===
 2 from django.forms import widgets
 3 from django.forms import fields
 4 from django import forms
 5 from app02 import models
 6 
 7 class UserInfoForm(forms.Form):
 8     user = fields.CharField(
 9         required=False,
10         widget = widgets.Textarea(
11             attrs={
12                 'class':'c1'
13             }
14         )
15     )
16     pwd = fields.CharField(
17         max_length=12,
18         widget = widgets.PasswordInput(attrs={
19             'class':'c1'
20         })
21     )
22 
23     user_type = fields.ChoiceField(
24         choices=[(1,'普通用户'),(2,'超级用户'),],
25         widget = widgets.Select(choices=[])
26     )
27 
28 ===2.views.py文件===
29 from django.shortcuts import render
30 from app02.forms import UserInfoForm
31 
32 def index(request):
33     obj = UserInfoForm()
34     return render(request,'app02/index.html',{'obj':obj})
35 
36 ===3.index.html===
37 <!DOCTYPE html>
38 <html lang="en">
39 <head>
40     <meta charset="UTF-8">
41     <title>Title</title>
42 </head>
43 <body>
44 <h1>c测试</h1>
45     <p>{{ obj.user }}</p>
46     <p>{{ obj.pwd }}</p>
47     <p>{{ obj.user_type }}</p>
48    
49 </body>
50 </html>
51 ===4.models.py文件===
52 from django.db import models
53 
54 # Create your models here.
55 class UserType(models.Model):
56     name = models.CharField(max_length=32)
57 
58 class User(models.Model):
59     name = models.CharField(max_length=32)
60     pwd = models.CharField(max_length=32)
61 
62 ===5.urls.py===
63 from django.conf.urls import url,include
64 from app02 import views
65 
66 urlpatterns = [
67      url(r'^index/$', views.index),
68 ]

2、Form调用数据库字段

注:因为models中的类字段,均为静态字段,因此,在每次运行后,字段即永久驻留内存(除非重启服务),每次刷新后,因为创建的对象是对类的静态变量的深拷贝,因此数据库中新添加的字段不会因为刷新而自动更新。

 1 ===1.forms.py===
 2 from django.forms import widgets
 3 from django.forms import fields
 4 from django import forms
 5 from app02 import models
 6 
 7 class UserInfoForm(forms.Form):
 8     user = fields.CharField(
 9         required=False,
10         widget = widgets.Textarea(
11             attrs={
12                 'class':'c1'
13             }
14         )
15     )
16     pwd = fields.CharField(
17         max_length=12,
18         widget = widgets.PasswordInput(attrs={
19             'class':'c1'
20         })
21     )
22 
23     user_type = fields.ChoiceField(
24         
25         #choices= models.UserType.objects.values_list('id','name'),   #红色为在forms.py中执行choice的方法二
26         #widget = widgets.Select
27     )
28 ===2.views.py===
29 from django.shortcuts import render
30 from app02.forms import UserInfoForm
31 from app02 import models
32 # Create your views here.
33 def index(request):
34     obj = UserInfoForm()
35     #obj.fields['user_type'].choices = models.UserType.objects.values_list('id','name')    #以上粉色内容为直接在views.py中执行的choice方法一
36     return render(request,'app02/index.html',{'obj':obj})
37 
38 ===3.index.html===
39 <!DOCTYPE html>
40 <html lang="en">
41 <head>
42     <meta charset="UTF-8">
43     <title>Title</title>
44 </head>
45 <body>
46 <h1>测试</h1>
47     <p>{{ obj.user }}</p>
48     <p>{{ obj.pwd }}</p>
49     <p>{{ obj.user_type }}</p>
50 </body>
51 </html>
52 ===3.models.py===
53 from django.db import models
54 
55 # Create your models here.
56 class UserType(models.Model):
57     name = models.CharField(max_length=32)
58 
59 class User(models.Model):
60     name = models.CharField(max_length=32)
61     pwd = models.CharField(max_length=32)
62 ===4.urls.py===
63 from django.conf.urls import url,include
64 from django.contrib import admin
65 from app02 import views
66 
67 urlpatterns = [
68      url(r'^index/$', views.index),
69 ]

3、Form表单不需要重启服务即可load数据的方法:

 1 ===1.forms.py===
 2 from django.forms import widgets
 3 from django.forms import fields
 4 from django import forms
 5 from app02 import models
 6 
 7 class UserInfoForm(forms.Form):
 8     user = fields.CharField(
 9         required=False,
10         widget = widgets.Textarea(
11             attrs={
12                 'class':'c1'
13             }
14         )
15     )
16     pwd = fields.CharField(
17         max_length=12,
18         widget = widgets.PasswordInput(attrs={
19             'class':'c1'
20         })
21     )
22 
23     user_type = fields.ChoiceField(     
24         choices= models.UserType.objects.values_list('id','name'),
25         widget = widgets.Select(choices)
26     )
27 
28  ===2.views.py===
29 from django.shortcuts import render
30 from app02.forms import UserInfoForm
31 from app02 import models
32 # Create your views here.
33 def index(request):
34     obj = UserInfoForm()
35     obj.fields['user_type'].choices = models.UserType.objects.values_list('id','name')
36     return render(request,'app02/index.html',{'obj':obj})
37 ===3.index.html===
38 <!DOCTYPE html>
39 <html lang="en">
40 <head>
41     <meta charset="UTF-8">
42     <title>Title</title>
43 </head>
44 <body>
45 <h1>测试</h1>
46     <p>{{ obj.user }}</p>
47     <p>{{ obj.pwd }}</p>
48     <p>{{ obj.user_type }}</p>
49 </body>
50 </html>
51 ===4.models.py===
52 from django.db import models
53 
54 # Create your models here.
55 class UserType(models.Model):
56     name = models.CharField(max_length=32)
57 
58 class User(models.Model):
59     name = models.CharField(max_length=32)
60     pwd = models.CharField(max_length=32)
61 
62 ===5.urls.py===
63 from django.conf.urls import url,include
64 from django.contrib import admin
65 from app02 import views
66 
67 urlpatterns = [
68      url(r'^index/$', views.index),
69 ]

 4、通过Forms初始化类,实现Forms

 1 ===1.forms.py===
 2 from django.forms import widgets
 3 from django.forms import fields
 4 from django import forms
 5 from app02 import models
 6 
 7 class UserInfoForm(forms.Form):
 8     user = fields.CharField(
 9         required=False,
10         widget = widgets.Textarea(
11             attrs={
12                 'class':'c1'
13             }
14         )
15     )
16     pwd = fields.CharField(
17         max_length=12,
18         widget = widgets.PasswordInput(attrs={
19             'class':'c1'
20         })
21     )
22 
23     user_type = fields.ChoiceField(
24      
25     )
26     # user_type2 = fields.CharField(
27     #     widget = widgets.Select(choices=[])
28     # )
29 
30      def __init__(self,*args,**kwargs):
31          super(UserInfoForm,self).__init__(*args,**kwargs)
32          self.fields['user_type'].choices = models.UserType.objects.values_list('id','name')
33         
34 ===2.views.py===
35 from django.shortcuts import render
36 from app02.forms import UserInfoForm
37 from app02 import models
38 # Create your views here.
39 def index(request):
40     obj = UserInfoForm()
41     return render(request,'app02/index.html',{'obj':obj})
42 
43 ===3.index.html===
44 <!DOCTYPE html>
45 <html lang="en">
46 <head>
47     <meta charset="UTF-8">
48     <title>Title</title>
49 </head>
50 <body>
51 <h1>form测试</h1>
52     <p>{{ obj.user }}</p>
53     <p>{{ obj.pwd }}</p>
54     <p>{{ obj.user_type }}</p>
55 </body>
56 </html>
57 
58 ===4.models.py===
59 from django.db import models
60 
61 # Create your models here.
62 class UserType(models.Model):
63     name = models.CharField(max_length=32)
64 
65 class User(models.Model):
66     name = models.CharField(max_length=32)
67     pwd = models.CharField(max_length=32)
68 
69 ===5.urls.py===
70 from django.conf.urls import url,include
71 from django.contrib import admin
72 from app02 import views
73 
74 urlpatterns = [
75      url(r'^index/$', views.index),
76 ]

5、通过Charfield实现choice表单

 1 ===1.forms.py===
 2 from django.forms import widgets
 3 from django.forms import fields
 4 from django import forms
 5 from app02 import models
 6 
 7 class UserInfoForm(forms.Form):
 8     user = fields.CharField(
 9         required=False,
10         widget = widgets.Textarea(
11             attrs={
12                 'class':'c1'
13             }
14         )
15     )
16     pwd = fields.CharField(
17         max_length=12,
18         widget = widgets.PasswordInput(attrs={
19             'class':'c1'
20         })
21     )
22 
23     user_type = fields.ChoiceField(
24          #choices=[(1,'普通用户'),(2,'超级用户'),],
25          #choices= models.UserType.objects.values_list('id','name'),
26      
27         widget = widgets.Select(choices=[])
28     )
29     user_type2 = fields.CharField(
30         widget = widgets.Select(choices=[])
31     )
32 
33     def __init__(self,*args,**kwargs):
34         super(UserInfoForm,self).__init__(*args,**kwargs)
35         # self.fields['user_type'].choices = models.UserType.objects.values_list('id','name')
36         self.fields['user_type2'].widget.choices = models.UserType.objects.values_list('id','name')
37 
38 ===2.views.py===
39 from django.shortcuts import render
40 from app02.forms import UserInfoForm
41 from app02 import models
42 # Create your views here.
43 def index(request):
44     obj = UserInfoForm()
45     #obj.fields['user_type'].choices = models.UserType.objects.values_list('id','name')
46     return render(request,'app02/index.html',{'obj':obj})
47 
48 ===3.index.html===
49 <!DOCTYPE html>
50 <html lang="en">
51 <head>
52     <meta charset="UTF-8">
53     <title>Title</title>
54 </head>
55 <body>
56 <h1>form测试</h1>
57     <p>{{ obj.user }}</p>
58     <p>{{ obj.pwd }}</p>
59     <p>{{ obj.user_type }}</p>
60     <p>{{ obj.user_type2 }}</p>
61 </body>
62 </html>
63 ===4.models.py===
64 from django.db import models
65 
66 # Create your models here.
67 class UserType(models.Model):
68     name = models.CharField(max_length=32)
69 
70 class User(models.Model):
71     name = models.CharField(max_length=32)
72     pwd = models.CharField(max_length=32)
73 
74 ===5.urls.py===
75 from django.conf.urls import url,include
76 from django.contrib import admin
77 from app02 import views
78 
79 urlpatterns = [
80      url(r'^index/$', views.index),
81 ]

6、通过ModelChoiceField调用

 1 ===1.forms.py===
 2 from django.forms import widgets
 3 from django.forms import fields
 4 from django import forms
 5 from app02 import models
 6 from django.forms.models import ModelChoiceField
 7 class UserInfoForm(forms.Form):
 8     user = fields.CharField(
 9         required=False,
10         widget = widgets.Textarea(
11             attrs={
12                 'class':'c1'
13             }
14         )
15     )
16     pwd = fields.CharField(
17         max_length=12,
18         widget = widgets.PasswordInput(attrs={
19             'class':'c1'
20         })
21     )
22 
23     user_type = fields.ChoiceField(
24         #     #choices=[(1,'普通用户'),(2,'超级用户'),],
25         #     #choices= models.UserType.objects.values_list('id','name'),
26         #
27         widget = widgets.Select(choices=[])
28      )
29     user_type2 = fields.CharField(
30         widget = widgets.Select(choices=[])
31     )
32 
33     user_type3=ModelChoiceField(
34         queryset=models.UserType.objects.all()
      #queryset, #查询数据库中的数据
       #empty_label="---------" #默认空显示内容
#to_field_name=None, #HTML中的value值的对应字段
   #limit_choices_to=None #ModelForm中对queryset二次筛选
35 )
36 37 def __init__(self,*args,**kwargs): 38 super(UserInfoForm,self).__init__(*args,**kwargs) 39 self.fields['user_type'].choices = models.UserType.objects.values_list('id','name') 40 self.fields['user_type2'].widget.choices = models.UserType.objects.values_list('id','name') 41 ===2.views.py=== 42 from django.shortcuts import render 43 from app02.forms import UserInfoForm 44 from app02 import models 45 # Create your views here. 46 def index(request): 47 obj = UserInfoForm() 48 #obj.fields['user_type'].choices = models.UserType.objects.values_list('id','name') 49 return render(request,'app02/index.html',{'obj':obj}) 50 ===3.index.html=== 51 <!DOCTYPE html> 52 <html lang="en"> 53 <head> 54 <meta charset="UTF-8"> 55 <title>Title</title> 56 </head> 57 <body> 58 <h1>form测试</h1> 59 <p>{{ obj.user }}</p> 60 <p>{{ obj.pwd }}</p> 61 <p>{{ obj.user_type }}</p> 62 <p>{{ obj.user_type2 }}</p> 63 <p>{{ obj.user_type3 }}</p> 64 </body> 65 </html> 66 ===4.models.py=== 67 from django.db import models 68 69 # Create your models here. 70 class UserType(models.Model): 71 name = models.CharField(max_length=32) 72 73 def __str__(self): 74 return self.name #只有此种形式需要加入此内容 75 76 class User(models.Model): 77 name = models.CharField(max_length=32) 78 pwd = models.CharField(max_length=32) 79 80 ===5.urls.py=== 81 from django.conf.urls import url,include 82 from django.contrib import admin 83 from app02 import views 84 85 urlpatterns = [ 86 87 url(r'^index/$', views.index), 88 ]

 二、Form验证(钩子)

验证过程:

-每一个字段(正则,字段钩子)

-整体的错误信息

self._clean_fields()
self._clean_form()
self._post_clean()

1.表单付默认值:

1 ===2.views.py===
2 from django.shortcuts import render
3 from app02.forms import UserInfoForm
4 from app02 import models
5 # Create your views here.
6 def index(request):
7     obj = UserInfoForm({'user':'zhangsan'})
8     #obj.fields['user_type'].choices = models.UserType.objects.values_list('id','name')
9     return render(request,'app02/index.html',{'obj':obj})

2.钩子

 1 ===1.forms.py===
 2 from django.core.exceptions import ValidationError        
 3 class RegisterForm(forms.Form):
 4     uesr = forms.CharField()
 5     email = forms.EmailField()
 6     
 7     #自定义验证规则,首先要上面默认的正则表达式完成,才能执行下面的验证方法
 8     def clean_user(self):               #clean_字段名,对单个字段进行验证
 9         c = models.User.objects.filter(name=self.cleaned_data['user']).count()
10         if not c:
11             return self.cleaned_data['user']
12         else:
13             
14             raise ValidationError('用户名已经存在',code='xxx')
15     
16     def clean_email(self):        
17         return self.cleaned_data['email']
18     
19     def clean(self):     #对整体进行验证
20         c = models.User.objects.filter(name=self.cleaned_data['user'],pwd=self.cleaned_data['pwd']).count()
21         if c:
22             return self.cleaned_data
23         else:
24             raise ValidationError('用户名或密码错误')
25         
26     def _post_clean(self):
27         pass

3.forms信息存储位置

 1 def register(request):
 2     from app02.forms import RegisterForm
 3     obj = RegisterForm(request.POST)
 4     if obj.is_valid():
 5         obj.cleaned_data    #存储经过验证的正确数据
 6     else:
 7         obj.errors
 8         {
 9             '__all__':[]   #存储forms表单整体错误数据,如用户名密码不匹配,也可写成NON_FIELD_ERRORS==__all__
10             'user':[{'code':'required','message':'xxxx'}],
11             'pwd':[{'code':'required','message':'xxx'}],
12         }

 

posted @ 2017-02-22 12:23  jidi_78  阅读(167)  评论(0)    收藏  举报