Django之form组件

Django之form组件

form组件的具有作用就是检验字段的功能。
例如:注册功能(简易版,form+models)
 1 #创建表
 2 class UserInfo(models.Model):
 3     name = models.CharField(max_length=32)
 4     pwd = models.CharField(max_length=32)
 5     email = models.EmailField()
 6     tel = models.CharField(max_length=32)
 7 
 8     
 9 #前端页面
10 <!DOCTYPE html>
11 <html lang="en">
12 <head>
13     <meta charset="UTF-8">
14     <title>reg</title>
15 </head>
16 <body>
17 <form action="" method="post">
18 
19     {% csrf_token %}
20     <div>
21         <label for="user">用户</label>
22         <p><input type="text" name="name" id="name"></p>
23     </div>
24 
25     <div>
26         <label for="pwd">密码</label>
27         <p><input type="password" name="pwd" id="pwd"></p>
28     </div>
29     <div>
30         <label for="r_pwd">确认密码</label>
31         <p><input type="password" id="r_pwd" name="r_pwd"></p>
32     </div>
33     <input type="submit">
34 </form>
35 </body>
36 </html>
37 
38 #视图函数
39 from django.forms import widgets
40 from django import forms
41 
42 wid_01 = widgets.TextInput(attrs={"class":"from-control"})
43 wid_02 = widgets.PasswordInput(attrs={"class":"from-control"})
44 
45 class UserForm(forms.Form):
46     name = forms.CharField(max_length=32,
47                            widget=wid_01
48                            )
49     pwd = forms.CharField(max_length=32,widget=wid_02)
50     r_pwd = forms.CharField(max_length=32,widget=wid_02)
51     email = forms.EmailField(widget=wid_01)
52     tel = forms.CharField(max_length=32,widget=wid_01)
53 
54 def reg(request):
55     if request.method == 'POST':
56         form = UserForm(request.POST)
57         if form.is_valid():
58             print(form.cleaned_data)    #所有校验成功的字段
59         else:
60             print(form.cleaned_data)
61             print(form.errors)          #所有错误的字段,{"字段":["值"]}
62             print(form.errors.get('name'))   #[错误信息]
63         return HttpResponse('ok')
64     form = UserForm()
65     return render(request,'reg.html',locals())
View Code

form标签渲染

#方式一
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
   <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h3>注册页面</h3>
<div class="container">
    <div class="row">
        <div class="col-md-6 col-lg-offset-3">

                <form action="" method="post">
                    {% csrf_token %}
                    <div>
                        <label for="">用户名</label>
                        {{ form.name }}
                    </div>
                    <div>
                        <label for="">密码</label>
                        {{ form.pwd }}
                    </div>
                    <div>
                        <label for="">确认密码</label>
                        {{ form.r_pwd }}
                    </div>
                    <div>
                        <label for=""> 邮箱</label>
                        {{ form.email }}
                    </div>

                    <input type="submit" class="btn btn-default pull-right">
                </form>
        </div>
    </div>
</div>

</body>
</html>
#后端传入form变量

#方式二
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
   <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>

<form action="" method="post">
    {% csrf_token %}
    {% for field in form %}    
        <div>
            <label for="">{{ field.label }}</label>
            {{ field }}
        </div>
    {% endfor %}
    <input type="submit" class="btn btn-default pull-right">
</form>

</body>
</html>


#渲染方式3 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
   <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>

<form action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" class="btn btn-default pull-right">
</form>

</body>
</html>

form组件之钩子

 1 #视图
 2 from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
 3 from django.forms import widgets
 4 from django import forms
 5 
 6 wid_01 = widgets.TextInput(attrs={"class":"from-control"})
 7 wid_02 = widgets.PasswordInput(attrs={"class":"from-control"})
 8 
 9 class UserForm(forms.Form):
10     name = forms.CharField(max_length=32,
11                            widget=wid_01
12                            )
13     pwd = forms.CharField(max_length=32,widget=wid_02)
14     r_pwd = forms.CharField(max_length=32,widget=wid_02)
15     email = forms.EmailField(widget=wid_01)
16     tel = forms.CharField(max_length=32,widget=wid_01)
17 
18     #局部钩子
19     def clean_name(self):
20         val = self.cleaned_data.get("name")
21         if not val.isdigit():
22             return val
23         else:
24             raise ValidationError("用户名不能全为数字!")
25 
26     #全局钩子
27     def clean(self):
28         pwd = self.cleaned_data.get("pwd")
29         r_pwd = self.cleaned_data.get("r_pwd")
30         if pwd == r_pwd:
31             return self.cleaned_data
32         else:
33             raise ValidationError("两次密码不一致!")
34 
35 def reg(request):
36     if request.method == 'POST':
37         form = UserForm(request.POST)
38         if form.is_valid():
39             print(form.cleaned_data)    #所有校验成功的字段
40         else:
41             clear_error = form.errors.get("__all__")
42             print('clear_error', clear_error)
43         return HttpResponse('ok')
44     form = UserForm()
45     print(form)
46     return render(request,'reg.html',locals())
47 
48 #前端
49 <!DOCTYPE html>
50 <html lang="en">
51 <head>
52     <meta charset="UTF-8">
53     <title>Title</title>
54    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
55     <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
56 </head>
57 <body>
58 <form action="" method="post" novalidate>
59     {% csrf_token %}
60     {% for filed in form %}
61         <div>
62             <label for="">{{ filed.label }}</label>
63             {{ filed }}
64             <span class="pull-right" style="color: red">
65                 {% if filed.label == 'R pwd' %}
66                 <span>{{ clear_error.0 }}</span>
67                 {% endif %}
68                 {{ filed.errors.0 }}
69             </span>
70         </div>
71     {% endfor %}
72     <input type="submit" class="btn btn-primary pull-right">
73 </form>
74 </body>
75 </html>
View Code

Django组件modelform

  1 #urls.py
  2 urlpatterns = [
  3     url(r'^admin/', admin.site.urls),
  4     url(r'^add_book/', views.AddBookView.as_view()),
  5     url(r'^edit_book/(\d+)', views.EditBookView.as_view()),
  6 ]
  7 
  8 #models.py
  9 from django.db import models
 10 
 11 # Create your models here.
 12 
 13 
 14 class Author(models.Model):
 15     nid = models.AutoField(primary_key=True)
 16     name=models.CharField( max_length=32)
 17     age=models.IntegerField()
 18     # 与AuthorDetail建立一对一的关系
 19     authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE)
 20     def __str__(self):
 21         return self.name
 22 class AuthorDetail(models.Model):
 23 
 24     nid = models.AutoField(primary_key=True)
 25     birthday=models.DateField()
 26     telephone=models.BigIntegerField()
 27     addr=models.CharField( max_length=64)
 28 
 29 class Publish(models.Model):
 30     nid = models.AutoField(primary_key=True)
 31     name=models.CharField( max_length=32)
 32     city=models.CharField( max_length=32)
 33     email=models.EmailField()
 34     def __str__(self):
 35         return self.name
 36 
 37 class Book(models.Model):
 38     nid = models.AutoField(primary_key=True)
 39     title = models.CharField( max_length=32)
 40     publishDate=models.DateField()
 41     price=models.DecimalField(max_digits=5,decimal_places=2)
 42     # 与Publish建立一对多的关系,外键字段建立在多的一方
 43     publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
 44     # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
 45     authors=models.ManyToManyField(to='Author',)
 46 
 47 #视图函数
 48 from django.forms import ModelForm
 49 
 50 class BookModelForm(ModelForm):
 51     class Meta:
 52         model=Book
 53         fields="__all__"
 54 
 55 class AddBookView(View):
 56 
 57     def get(self,request):
 58         form=BookModelForm()
 59         return render(request,"addbook.html",locals())
 60 
 61     def post(self,request):
 62         form=BookModelForm(request.POST)
 63         if form.is_valid():
 64             # print("cleaned_data:",form.cleaned_data)
 65             # form.cleaned_data.pop("authors")
 66             # Book.objects.create(**form.cleaned_data)
 67             form.save()
 68             return HttpResponse("OK")
 69         else:
 70             print(form.cleaned_data)
 71             print(form.errors)
 72         return HttpResponse("OK")
 73 
 74 class EditBookView(View):
 75 
 76     def get(self,request,id):
 77         edit_book=Book.objects.get(pk=id)
 78         form = BookModelForm(instance=edit_book)
 79         return render(request,"editbook.html",locals())
 80 
 81     def post(self,request,id):
 82         edit_book = Book.objects.get(pk=id)
 83         form=BookModelForm(request.POST,instance=edit_book)
 84         if form.is_valid():
 85             form.save()
 86             return HttpResponse("OK")
 87         else:
 88             print(form.cleaned_data)
 89             print(form.errors)
 90         return HttpResponse("OK")
 91     
 92 #添加图书页面
 93 <!DOCTYPE html>
 94 <html lang="en">
 95 <head>
 96     <meta charset="UTF-8">
 97     <title>Title</title>
 98 </head>
 99 <body>
100 
101 
102 <form action="" novalidate method="post">
103 
104     {% csrf_token %}
105     {{ form.as_p }}
106 
107     <input type="submit">
108 
109 </form>
110 
111 </body>
112 </html>
113 
114 
115 #编辑图书页面
116 <!DOCTYPE html>
117 <html lang="en">
118 <head>
119     <meta charset="UTF-8">
120     <title>Title</title>
121 </head>
122 <body>
123 
124 <form action="" novalidate method="post">
125     {% csrf_token %}
126     {{ form.as_p }}
127     <input type="submit">
128 </form>
129 </body>
130 </html>
131 
132 #modelsform
133 Model + Form ==> ModelForm
134 它具有的功能有:
135     1.验证
136     2.数据库操作
137 
138 model有操作数据库的字段,form验证也有那几个字段,虽然耦合度降低,但是代码是有重复的。如果利用model里的字段,那是不是form里的字段就不用写了,可以参考上面分开写的方式。
139 
140 fields = "__all__"上面展示所有的,可不可以展示指定的列:
141     fields = ['username','email']   # 显示指定列
142     exclude = ['username']          # 排除指定列
143 
144 #form.save()做了那些操作?
145         if self.errors:
146             raise ValueError(
147                 "The %s could not be %s because the data didn't validate." % (
148                     self.instance._meta.object_name,
149                     'created' if self.instance._state.adding else 'changed',
150                 )
151             )
152         if commit:
153             # If committing, save the instance and the m2m data immediately.
154             self.instance.save()    #指当前的model类
155             self._save_m2m()    #指,保存m2对象
156         else:
157             self.save_m2m = self._save_m2m
158             return self.instance #model对象
View Code

 

posted @ 2018-06-03 22:37  健林  阅读(84)  评论(0)    收藏  举报