Django:(5)分页器 & forms组件
Django组件:分页器
目录结构:
urls.py
- from django.contrib import admin
- from django.urls import path
- from app01 import views
- urlpatterns = [
- path('admin/', admin.site.urls),
- path(r"index/",views.index)
- ]
models.py
- from django.db import models
- # Create your models here.
- class Book(models.Model):
- title = models.CharField(max_length=32)
- price = models.DecimalField(decimal_places=2,max_digits=8)
views.py
- from django.shortcuts import render
- # Create your views here.
- from app01.models import Book
- # 导入分页器
- from django.core.paginator import Paginator,EmptyPage
- def index(request):
- """
- # 批量插入数据
- # for i in range(100):
- # Book.objects.create(title="book_%s"%i,price=i*i)
- # 但上面的批量插入方式效率低,因为需要往数据库中insert100次;不如把100条记录先准备好,只insert一次, insert ... values(),(),...
- book_list = []
- for i in range(100): # 这个过程中和数据库无关,只是实例化出了100个Book对象(因为没有 save() )
- book_obj = Book(title="book_%s"%i,price=i*i)
- book_list.append(book_obj)
- # bulk_create():批量插入数据
- Book.objects.bulk_create(book_list) # 效果就是:一条insert后面有100条数据
- :param request:
- :return:
- """
- book_list = Book.objects.all() # .objects.all():相当于一个 生成器,并不是一次性把数据从数据库全部取了出来
- # Paginator(object_list,per_page):第一个参数是对象列表,第二个是每页显示多少条数据
- paginator = Paginator(book_list,3) # 得到一个Paginator分页器对象
- # paginator的属性
- # print("count:",paginator.count) # paginator.count:统计Book_list里面有多少条数据
- # print("num_pages:",paginator.num_pages) # paginator.num_pages:总共有多少页
- # print("page_range:",paginator.page_range) # paginator.page_range:页码的列表
- # count: 100
- # num_pages: 13
- # page_range: range(1, 14) # range(1,14) 是因为range顾头不顾尾
- """
- # 显示某一页具体数据的两种方式
- page1 = paginator.page(1) # 第一页的page对象;page1可进行迭代处理
- print("objects_list",page1.object_list) # page1.object_list:这一页所有的model记录对象;QuerySet类型
- # page1也可进行遍历
- for i in page1:
- print(i)
- # 所以想要显示某一页的具体数据可以通过 page1.object_list 或者 遍历 page1 这两种方法
- """
- # 为了不把页码写死,需要动态的传入页码
- current_page_num = int(request.GET.get("page", 1)) # get中的1表示默认获取到的值
- # page_range:用于在模板中渲染多少个的页码的变量
- # 固定显示的最大页码数为11页
- if paginator.num_pages > 11:
- # 如果总页码数大于11,则固定显示11页
- # 如果当前页为最前面的5个, 则要让 page_range 固定为 range(1,12)
- if current_page_num - 5 < 1:
- page_range = range(1,12)
- # 如果当前页为最后面的5个, 则要让 page_range 固定为 range(paginator.num_pages-10,paginator.num_pages+1) (即最后面的11个页码)
- elif current_page_num + 5 > paginator.num_pages:
- page_range = range(paginator.num_pages-10,paginator.num_pages+1)
- else: # 中间的情况
- page_range = range(current_page_num-5,current_page_num+6)
- else:
- # 如果小于11页,就显示全部页码
- page_range = paginator.page_range
- # 如果页码错误(current_page_num不在有效页码范围之内),就让其显示第一页
- try:
- current_page = paginator.page(current_page_num) # 当前页
- """
- # page对象的方法:
- print(current_page.has_next()) # page.has_next():是否有下一页
- print(current_page.next_page_number()) # page.next_page_number(): 下一页的页码
- print(current_page.has_previous()) # 是否有上一页
- print(current_page.previous_page_number()) # 上一页的页码
- """
- except EmptyPage as e:
- current_page = paginator.page(1)
- return render(request,"index.html",locals())
index.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <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>
- <ul>
- {#此时不要循环所有数据(book_list),而是只循环当前页的数据 #}
- {% for book in current_page %}
- <li>{{ book.title }}:{{ book.price }}</li>
- {% endfor %}
- </ul>
- <nav aria-label="Page navigation">
- <ul class="pagination">
- {# 另一种方法:直接利用 current_page.has_previous 和 current_page.previous_page_number #}
- {# 先判断它有没有上一页 #}
- {% if current_page.has_previous %}
- <li>
- {# 通过过滤器让 current_page_num 减1(加 -1);这是一种方法 #}
- {# <a href="?page={{ current_page_num|add:-1 }}" aria-label="Previous">#}
- <a href="?page={{ current_page.previous_page_number }}" aria-label="Previous">
- <span aria-hidden="true">上一页</span>
- </a>
- </li>
- {# 如果没有上一页,则让该li标签 disabled #}
- {% else %}
- <li class="disabled">
- <a href="" aria-label="Previous">
- <span aria-hidden="true">上一页</span>
- </a>
- </li>
- {% endif %}
- {# 循环页码总数,添加分页器的页数 #}
- {# 但为了只显示固定数量的页码数,我们应该只循环page_range这个变量,而不是所有的页码 #}
- {# {% for item in paginator.page_range %}#}
- {% for item in page_range %}
- {% if current_page_num == item %}
- {# a标签中的 herf 如果只有请求数据,那么默认的IP、端口和路径就是当前页面的 #}
- <li class="active" ><a href="?page={{ item }}">{{ item }}</a></li>
- {# 点击分页器中的某一页码,其颜色就会发生变化:在li标签中添加 class="active" #}
- {% else %}
- <li><a href="?page={{ item }}">{{ item }}</a></li>
- {% endif %}
- {% endfor %}
- {# <li><a href="?page={{ current_page_num|add:1 }}" aria-label="Next"><span aria-hidden="true">下一页</span></a></li>#}
- {# 下一页同理: .has_next 和 next_page_num #}
- {% if current_page.has_next %}
- <li><a href="?page={{ current_page.next_page_number }}" aria-label="Next"><span aria-hidden="true">下一页</span></a></li>
- {% else %}
- <li class="disabled"><a href="" aria-label="Next"><span aria-hidden="true">下一页</span></a></li>
- {% endif %}
- </ul>
- </nav>
- </body>
- </html>
django组件 ---- forms组件
(1) forms组件之校验字段功能
urls.py
- from django.contrib import admin
- from django.urls import path
- from app01 import views
- urlpatterns = [
- path('admin/', admin.site.urls),
- path(r"reg/",views.reg)
- ]
views.py
- from django.shortcuts import render,HttpResponse
- # Create your views here.
- # 导入forms组件
- from django import forms
- class UserForm(forms.Form): # 类名可以自己定义,但需要继承 forms.Form
- # 字段名称 = 校验规则
- # 校验规则都有一个 非空 规则
- name = forms.CharField(min_length=4) # name这个字段必须是最少为4位的字符串
- psw = forms.CharField(min_length=4)
- r_psw = forms.CharField(min_length=4)
- email = forms.EmailField() # forms.EmailField():邮箱校验规则
- tel = forms.CharField()
- def reg(request):
- if request.method == "POST":
- """
- # forms组件的应用:
- form = UserForm({"name":"neo","email":"123@qq.com","xx":"666naosid"}) # 把待校验的信息以字典的形式(字典的键值必须和类的字段一致)放入 UserForm中实例化一个对象;该对象有 is_valid() 的方法进行校验是否符合定义的校验规则
- # 如果字典中的某个key在UserForm中的所有字段中不存在,且UserForm中的【所有】字段都校验正确,则这些不存在的key-value 不会对校验结果(form.is_valid())产生影响;但如果UserForm中不是【所有的】字段都校验正确,则 form.is_valid()返回 False
- # 如: UserForm({"name":"neo123","email":"123@qq.com","xxx":"123465"}) 返回True,因为 name 和 email都校验正确(UserForm所有的字段);但 UserForm({"name":"neo123","xxx":"123465"}) 会返回 False
- print(form.is_valid()) # is_valid() 返回Bool值
- # UserForm中的字段如果没有被全部校验(如:字典是没有 "name"= "xxx" 等),则返回False,因为 为空匹配
- if form.is_valid():
- print(form.cleaned_data) # 如果 所有的字段都校验成功,则 form会有一个 cleaned_data 的属性, form.cleaned_data 是一个包含所有正确信息的字典(不包含不存在的字段,即不包含与UserForm无关的字段)
- else: # 没有符合全部字段的校验规则
- print(form.cleaned_data) # 把 form.is_valid() 在校验过程中发现的符合校验规则的key-value放入 form.cleaned_data 这个字典中
- print(form.errors) # 把 form.is_valid() 在校验过程中发现的不符合校验规则的key-value(即错误信息)放入 form.errors 这个字典中;其数据类型可理解为一个字典,字典时的value是一个列表(django.forms.utils.ErrorList)放错误信息
- """
- # forms组件的校验功能
- print(request.POST)
- form = UserForm(request.POST) # request.POST(来自前端的form表单的name属性)本身就是一个字典,而且它的key和 UserForm的字段名一致(在reg.html中自己设置的);虽然 request.POST中有 csrf,但并不会影响校验结果(原因如上,只是多了一个无关的key-value而已)
- if form.is_valid():
- print(form.cleaned_data)
- else:
- print(form.cleaned_data)
- print(form.errors)
- print(type(form.errors)) # <class 'django.forms.utils.ErrorDict'> # 所以能用字典的方法去处理 form.errors
- return HttpResponse("ok")
- return render(request,"reg.html")
reg.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <form action="" method="post">
- {% csrf_token %}
- {# 为了form表单校验方便,表单控件是 name属性的值应该和forms组件(UserForm)中的字段一致 #}
- <p>用户名 <input type="text" name="name"></p>
- <p>密码 <input type="password" name="psw"></p>
- <p>确认密码 <input type="password" name="r_psw"></p>
- <p>邮箱 <input type="text" name="email"></p>
- <p>电话 <input type="text" name="tel"></p>
- <input type="submit">
- </form>
- </body>
- </html>
forms组件的渲染标签功能1:
还以上面的project为例
views.py
- from django.shortcuts import render,HttpResponse
- # Create your views here.
- # 导入forms组件
- from django import forms
- class UserForm(forms.Form): # 类名可以自己定义,但需要继承 forms.Form
- # 字段名称 = 校验规则
- # 校验规则都有一个 非空 规则
- name = forms.CharField(min_length=4) # CharField()可以渲染input标签
- psw = forms.CharField(min_length=4)
- r_psw = forms.CharField(min_length=4)
- email = forms.EmailField() # EmailField() 也可以渲染input标签
- tel = forms.CharField()
- def reg(request):
- if request.method == "POST":
- if form.is_valid():
- print(form.cleaned_data)
- else:
- print(form.cleaned_data)
- print(form.errors)
- print(type(form.errors))
- return HttpResponse("ok")
- # forms组件渲染方式1
- # 假如你不想自己去渲染 reg.html 中的form表单控件,你可以先用 UserForm 实例化一个对象 form,然后把这个 form 对象传到 render 中,最后在reg.html中利用 form对象去渲染 form表单控件
- form1 = UserForm() # get请求方式时传入 render() reg.html 中去渲染 form 表单控件
- return render(request,"reg.html",locals())
reg.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <h3>forms组件渲染方式1</h3>
- <form action="" method="post">
- {% csrf_token %}
- <p>用户名
- {# 通过传进来的 UserForm 的对象 form1.字段的形式,可直接渲染出 input标签,并且 input标签的name属性值为 form1这个对象的 字段名#}
- {{ form1.name }}
- </p>
- <p>密码 {{ form1.psw }}</p>
- <p>确认密码 {{ form1.r_psw }}</p>
- <p>邮箱 {{ form1.email }}</p>
- <p>电话 {{ form1.tel }}</p>
- {# CharField 校验规则能渲染 type="text"的input标签;EmailField 校验规则能渲染 type="email"的input标签#}
- {# 字段非常多的时候可以用这种方式#}
- <input type="submit">
- </form>
- </body>
- </html>
浏览器效果如下:
注意:forms组件的校验字段功能和渲染标签功能是两套功能;GET请求时进行渲染标签,POST时进行校验字段
forms组件的渲染标签功能2和3:
还以上面的project为例,views.py是要为UserForm这个类添加 label 属性
reg.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <h3>forms组件渲染方式2(推荐使用这种)</h3>
- <form action="" method="post">
- {% csrf_token %}
- {# 也可以 for 循环 views.py 传进来的 form1这个对象,for循环这个form1对象时得到的是 每一个 field对象(字段对象,如渲染方式1中的 form1.name,form1.psw等)#}
- {% for field in form1 %}
- <p>
- {# 字段对象有一个固有的属性 label,如 form1.psw.lable; 字段对象.label 在前端页面的展示效果会动态的跟随字段的名字而变化,如 form1.psw.label 在前端显示的input前的文字为 psw #}
- {# 如果想让 label 属性显示中文,需要在 UserForm 中为每个字段添加 lable属性值 #}
- <label for="">{{ field.label }}</label>
- {# field.label的作用是让input标签前添加label标签(中文描述);field就是 form1.字段名 #}
- {# 此时 field就是form1中的第一个字段对象 #}
- {{ field }}
- </p>
- {% endfor %}
- <input type="submit">
- <h3>forms组件渲染方式方法3</h3>
- <form action="" method="post">
- {# 直接只写一个 form1.as_p #}
- {{ form1.as_p }}
- {# 不推荐这种写法,这种渲染方式得到的form表单控件的结构是固定的:<p><label></label><input></p>,直接就写死了 #}
- </form>
- </form>
- </body>
- </html>
views.py 中的UserForm:
- # 导入forms组件
- from django import forms
- class UserForm(forms.Form): # 类名可以自己定义,但需要继承 forms.Form
- # 字段名称 = 校验规则
- # 校验规则都有一个 非空 规则
- name = forms.CharField(min_length=4,label="用户名") # 为每个 字段添加 label属性
- psw = forms.CharField(min_length=4,label="密码")
- r_psw = forms.CharField(min_length=4,label="确认密码")
- email = forms.EmailField(label="邮箱")
- tel = forms.CharField(label="电话")
浏览器效果如下:
forms组件渲染错误信息
views.py
- from django.shortcuts import render,HttpResponse
- # Create your views here.
- # 导入forms组件
- from django import forms
- class UserForm(forms.Form):
- name = forms.CharField(min_length=4,label="用户名")
- psw = forms.CharField(min_length=4,label="密码")
- r_psw = forms.CharField(min_length=4,label="确认密码")
- email = forms.EmailField(label="邮箱")
- tel = forms.CharField(label="电话")
- def reg(request):
- if request.method == "POST":
- print(request.POST)
- form1 = UserForm(request.POST)
- if form1.is_valid():
- print(form1.cleaned_data)
- else:
- print(form1.cleaned_data)
- print(form1.errors)
- print(type(form1.errors))
- # forms 组件渲染错误信息
- # GET请求时的form1对象和POST请求时的form1对象是不一样的;GET的form1没有传数据(未邦定数据的forms组件对象),POST的form1传了数据(邦定数据的forms组件对象)
- # 有错误信息时,依然把 reg.html 返回给前端;此时已输入的正确信息会在输入框中保留
- return render(request,"reg.html",locals())
- form1 = UserForm() # get请求方式时传入 render() reg.html 中去渲染 form 表单控件
- return render(request,"reg.html",locals())
reg.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <h3>forms组件渲染错误信息</h3>
- {#form表单控件的 novalidate 表示:当提交表单时不对表单数据(输入)进行验证#}
- <form action="" method="post" novalidate>
- {% csrf_token %}
- <p>
- {{ form1.name.label }}
- {# form1.字段不但能渲染出一个input标签,还能把 POST请求数据 在views.py 中过滤出来的正确信息 赋值给该 input 标签的value属性值;通过这种方式 在前端刷新页面时 已输入的正确信息能保留在输入框中 #}
- {{ form1.name }} <span>{{ form1.name.errors.0 }}</span>
- {# 每个字段对象都有一个 errors的属性;可通过 .errors.0 的方式 获取该错误信息 #}
- {# GET请求时不会显示错误信息,因为此时没有 errors, .errors.0 找不到信息就在前端页面上显示为空 #}
- </p>
- <p>{{ form1.psw.label }} {{ form1.psw }}<span>{{ form1.psw.errors.0 }}</span></p>
- <p>{{ form1.r_psw.label }} {{ form1.r_psw }}<span>{{ form1.r_psw.errors.0 }}</span></p>
- <p>{{ form1.email.label }} {{ form1.email }}<span>{{ form1.email.errors.0 }}</span></p>
- <p>{{ form1.tel.label }} {{ form1.tel }}<span>{{ form1.tel.errors.0 }}</span></p>
- <input type="submit">
- </form>
- </form>
- </body>
- </html>
forms组件的参数配置
forms组件的参数是在 views.py中的 UserForm中进行配置的,如:
- # forms组件的参数配置
- from django import forms
- from django.forms import widgets
- class UserForm(forms.Form):
- name = forms.CharField(min_length=4,label="用户名",error_messages={"required":"该字段不能为空"},
- widget=widgets.TextInput(attrs={"class":"form-control"})) # name这个字段必须是最少为4位的字符串 # 为每个 字段添加 label属性
- psw = forms.CharField(min_length=4,label="密码",error_messages={"required":"该字段不能为空"},
- widget=widgets.PasswordInput(attrs={"class":"form-control"}))
- r_psw = forms.CharField(min_length=4,label="确认密码",error_messages={"required":"该字段不能为空"},
- widget=widgets.PasswordInput(attrs={"class":"form-control"}))
- email = forms.EmailField(label="邮箱",widget=widgets.EmailInput(attrs={"class":"form-control"}),
- error_messages={"required": "该字段不能为空", "invalid": "邮箱格式错误"}) # forms.EmailField():邮箱校验规则
- tel = forms.CharField(label="电话",widget=widgets.TextInput(attrs={"class":"form-control"}),error_messages={"required":"该字段不能为空"})
- """
- 1. widget = widgets.TextInput():通过 添加属性 widget 能够控制渲染出来的input标签的 type 属性值,如: widget = widgets.TextInput() 表示渲染出 type="text"的input标签(默认值), widget= widgets.PasswordInput():text="passwrod" 的 input 标签,widget=widgets.EmailInput(): text="email" 的 input 标签
- 2. widget = widgets.TextInput(attrs={"class":"form-control"}):widget = widgets.TextInput()等参数中添加 attrs={"属性名":"属性值"} 能为渲染出来的input标签 添加特定的属性,如:widget = widgets.TextInput(attrs={"class":"form-control"}) 表示为渲染出来的 input标签添加 class="form-control"
- 3. error_messages={}:表示控制错误信息,如 error_messages={"required":"该字段不能为空","invalid":"格式错误"},"required"是“非空错误”的key,"invalid"是“格式错误”的key
- """
reg.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <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>
- <div class="container">
- <div class="row">
- <div class="col-md-6 col-md-offset-3">
- <h3>forms组件的参数配置</h3>
- <form action="" method="post" novalidate>
- {% csrf_token %}
- <p>
- {{ form1.name.label }}
- {{ form1.name }} <span>{{ form1.name.errors.0 }}</span>
- </p>
- <p>{{ form1.psw.label }} {{ form1.psw }}<span>{{ form1.psw.errors.0 }}</span></p>
- <p>{{ form1.r_psw.label }} {{ form1.r_psw }}<span>{{ form1.r_psw.errors.0 }}</span></p>
- <p>{{ form1.email.label }} {{ form1.email }}<span>{{ form1.email.errors.0 }}</span></p>
- <p>{{ form1.tel.label }} {{ form1.tel }}<span>{{ form1.tel.errors.0 }}</span></p>
- <input type="submit" class="btn btn-default">
- </form>
- </div>
- </div>
- </div>
- </body>
- </html>
局部钩子和全局钩子:
views.py
- from django.shortcuts import render
- # forms组件的参数配置
- from django import forms
- # 配置参数需要导入 widgets
- from django.forms import widgets
- # 钩子需要导入 ValidationError
- from django.core.exceptions import NON_FIELD_ERRORS,ValidationError
- from app01.models import UserInfo
- class UserForm(forms.Form):
- name = forms.CharField(min_length=4,label="用户名",error_messages={"required":"该字段不能为空"},
- widget=widgets.TextInput(attrs={"class":"form-control"})) # name这个字段必须是最少为4位的字符串 # 为每个 字段添加 label属性
- psw = forms.CharField(min_length=4,label="密码",error_messages={"required":"该字段不能为空"},
- widget=widgets.PasswordInput(attrs={"class":"form-control"}))
- r_psw = forms.CharField(min_length=4,label="确认密码",error_messages={"required":"该字段不能为空"},
- widget=widgets.PasswordInput(attrs={"class":"form-control"}))
- email = forms.EmailField(label="邮箱",widget=widgets.EmailInput(attrs={"class":"form-control"}),
- error_messages={"required": "该字段不能为空", "invalid": "邮箱格式错误"}) # forms.EmailField():邮箱校验规则
- tel = forms.CharField(label="电话",widget=widgets.TextInput(attrs={"class":"form-control"}),error_messages={"required":"该字段不能为空"})
- # 按照局部钩子校验字段
- def clean_name(self): # 只能叫 clean_字段名
- # 根据源码可知, 能执行 clean_字段 方法,说明已经通过了上面的 字段=校验规则 的校验
- # 校验用户名是否重名
- val = self.cleaned_data.get("name")
- # 从数据库中读取数据
- ret = UserInfo.objects.filter(name=val)
- if not ret:
- return val # 根据源码可知, return的 val 依然是 name 字段对应的值
- else:
- raise ValidationError("用户名已注册") # 抛出的异常名必须是 ValidationError;抛出的错误会放到 错误字典中
- def clean_tel(self):
- # 校验手机号是否为11位
- val = self.cleaned_data.get("tel")
- print(val)
- if len(val) == 11:
- return val # 如果手机号为11位,通过校验,则把手机号原封不动返回
- else:
- raise ValidationError("手机号必须为11位")
- # 一次校验里面用到多个校验的字段,就不能再用 上面的局部钩子方法,因为局部钩子方法一次只能校验一个字段;此时应该用全局钩子
- # clean():全局钩子;其它所有的校验规则校验完之后,才会走 clean()
- def clean(self):
- # 校验 psw 和 r_psw 是否一致
- psw = self.cleaned_data.get("psw")
- r_psw = self.cleaned_data.get("r_psw")
- # 先判断字段是否通过 字段校验和局部钩子,如果没有,则不进行全局钩子校验
- if psw and r_psw:
- if psw == r_psw:
- return self.cleaned_data # 通过全局钩子校验,则把 cleaned_data 原封返回
- else:
- raise ValidationError("两次密码不一致!") # 全局钩子的错误字典的形式:{"__all__":[....]},其key是 "__all__";这个异常类型不能通过 字段 获取到
- else: # 没通过字段校验和局部钩子,则把 干净的数据 clean_data 原封不动返回
- return self.cleaned_data
- def reg(request):
- if request.method == "POST":
- print(request.POST)
- form1 = UserForm(request.POST)
- if form1.is_valid():
- print(form1.cleaned_data)
- else:
- print(form1.cleaned_data)
- print(form1.errors)
- print(type(form1.errors))
- # 先把全局钩子的异常类型获取到
- err = form1.errors.get("__all__") # 获取全局钩子的错误信息
- # 同时要在 reg.html 中专门把此错误信息放到 r_psw后面
- return render(request,"reg.html",locals())
- form1 = UserForm()
- return render(request,"reg.html",locals())
reg.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <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>
- <div class="container">
- <div class="row">
- <div class="col-md-6 col-md-offset-3">
- <h3>forms组件的参数配置</h3>
- <form action="" method="post" novalidate>
- {% csrf_token %}
- <p>
- {{ form1.name.label }}
- {{ form1.name }} <span>{{ form1.name.errors.0 }}</span>
- </p>
- <p>{{ form1.psw.label }} {{ form1.psw }}<span>{{ form1.psw.errors.0 }}</span></p>
- <p>{{ form1.r_psw.label }}
- {{ form1.r_psw }}
- <span>{{ form1.r_psw.errors.0 }}</span>
- {# err.0 表示获取第一个错误信息;err:列表的形式;不在 views.py中直接 form1.errors.get("__all__")[0] 是防止报错 #}
- <span>{{ err.0 }}</span></p>
- <p>{{ form1.email.label }} {{ form1.email }}<span>{{ form1.email.errors.0 }}</span></p>
- <p>{{ form1.tel.label }} {{ form1.tel }}<span>{{ form1.tel.errors.0 }}</span></p>
- <input type="submit" class="btn btn-default">
- </form>
- </div>
- </div>
- </div>
- </body>
- </html>
Django:(5)分页器 & forms组件的更多相关文章
- [Django高级之forms组件]
[Django高级之forms组件] forms组件之校验字段 # 第一步:定义一个类,继承forms.Form # 第二步:在类中写字段,要校验的字段,字段属性就是校验规则 # 第三步:实例化得到一 ...
- django中的forms组件
form介绍 用户需要向后端提交一些数据时,我们常常把这些数据放在一个form表单里,采用form标签,里面包含一些input等标签把用户的数据提交给后端. 在给后端提交数据的时候,我们常常也需要对于 ...
- Django基础之forms组件中的ModelForm组件
Django的model form组件 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的例子来看一下这个东西怎么用:比如我们的数据库中有这样 ...
- django中的forms组件(权限信息校验,增删改查)
1.用处 1.用户请求数据验证 2.自动生成错误信息 3.打包用户提交的正确信息 4.如果其中有一个错误了,其他的正确,则保留上次输入的内容 5.自动创建input标签并可以设置样式 6.基于form ...
- Django框架的forms组件与一些补充
目录 一.多对多的三种创建方式 1. 全自动 2. 纯手撸(了解) 3. 半自动(强烈推荐) 二.forms组件 1. 如何使用forms组件 2. 使用forms组件校验数据 3. 使用forms组 ...
- forms组件补充与ModelForm简单使用与cookie与session
目录 forms组件钩子函数 forms组件字段参数 字段参数 validators详解 choices详解 widget详解 forms组件字段类型 ModelForm简单使用 cookie与ses ...
- Django学习——分页器基本使用、分页器终极用法、forms组件之校验字段、forms组件之渲染标签、forms组件全局钩子,局部钩子
内容 1 分页器基本使用 2 分页器终极用法 3 forms组件之校验字段 1 前端 <!DOCTYPE html> <html lang="en"> &l ...
- django之分页器、多对多关系、form校验组件
批量插入数据 bulk_create # 1.往书籍表中插入数据 1000 # for i in range(1000): # 这种插入方式 效率极低 # models.Book.objects.cr ...
- Django序列化组件与数据批量操作与简单使用Forms组件
目录 SweetAlert前端插件 Django自带的序列化组件 批量数据操作 分页器与推导流程 Forms组件之创建 Forms组件之数据校验 Forms组件之渲染标签 Forms组件之信息展示 S ...
随机推荐
- 转】[MySQL优化]为MySQL数据文件ibdata1瘦身
原博文出自于: http://blog.fens.me/category/%E6%95%B0%E6%8D%AE%E5%BA%93/page/2/ 感谢! [MySQL优化]为MySQL数据文件ibda ...
- [转]Business Model Canvas(商业模式画布):创业公司做头脑风暴和可行性测试的一大利器
本文转自:http://www.36kr.com/p/214438.html 本文来自First Round Review,他们准备的文章既讲故事,还同时向创业者提供可操作的建议,以助力打造优秀的公司 ...
- Webform 内置对象(Response对象、Request对象,QueryString)
Response对象:响应请求 Response.Write("<script>alert('添加成功!')</script>"); Response.Re ...
- 【工具】sublime使用技巧
Ctrl+N 新建一个编辑区,Ctrl+Shift+C 或!加 Ctrl+E新建一个骨架完好的文件. Ctrl+Shift+P开启命令模式,sshtml 切换html语法. esc退出,Ctrl+`打 ...
- 【Python】列表解析表达式
1.语法 [expression for iter_val in iterable] [expression for iter_val in iterable if cond_expr] 2.示例 s ...
- C# 移动开发 MasterDetailPage 侧滑
先上结果图: 虽然是跨平台的安卓和ios都可以运行,由于目前只配置了安卓的,ios的先不理. 我们先新建一个项目,跨平台应用: 可移植类库: 可移植项目右键添加新建项 选 Forms MasterDe ...
- logback配置模板
<?xml version="1.0" encoding="UTF-8"?> <configuration> <prope ...
- 【译】x86程序员手册37-第10章 初始化
Chapter 10 Initialization 第10章 初始化 After a signal on the RESET pin, certain registers of the 80386 a ...
- 使用Win7 64位旗舰版光盘映像安装Windows Home basic 64位操作系统
工作当中需要安装Windows home basic 64位操作系统,苦于手头没有该版本的安装光盘,也没时间下载其安装映像.因此,在现有资源“cn_windows_7_ultimate_with_sp ...
- AIX 10G HA RAC卸载
删除 1:crs_stat –t资源都停掉 2:停ha 3: 删除oracle 4:删除crs 5: 删除ha smit hacmp 6: 删除vg exportvg 7;卸载hacmp smitty