6.分页,form组件

1.分页功能

1.1批量插入数据

# 批量插入数据
    book_list = []
    for i in range(100):
        book = Book(title="book_%s"%i,price=i*i,publishDate="2012-12-12",publish_id=1)
        book_list.append(book)
    Book.objects.bulk_create(book_list)

1.2Paginator

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

    book_list = Book.objects.all()
    paginator = Paginator(book_list, 10)  # 每页显示10条数据
    print(paginator.count)  # 总数据数  105
    print(paginator.num_pages)  # 总页数  11
    print(paginator.page_range)  # 页码的列表  range(1, 12)
    page1 = paginator.page(1)  # 第一页的book对象列表
    print(page1)  # 
    for i in page1:  # 遍历第一页的所有数据对象
        print(i)  # Book object (16)
    print(page1.object_list)  # 第一页的所有数据[, ... ]

    page2 = paginator.page(2)
    print(page2.has_next())  # 是否有下一页 True
    print(page2.next_page_number())  # 下一页的页码 3
    print(page2.has_previous())  # 是否有上一页 True
    print(page2.previous_page_number())  # 上一页的页码 1

        # 抛错
    page=paginator.page(12)   # error:EmptyPage

    page=paginator.page("z")   # error:PageNotAnInteger

1.3分页案例

views.py

成都创新互联是一家专注于成都网站建设、网站制作与策划设计,宾县网站建设哪家好?成都创新互联做网站,专注于网站建设10年,网设计领域的专业建站公司;建站业务涵盖:宾县等地区。宾县做网站价格咨询:028-86922220

from django.shortcuts import render,HttpResponse
from django.core.paginator import Paginator,EmptyPage
from app1.models import *
def index(request):
    book_list = Book.objects.all()
    paginator = Paginator(book_list, 7)  # 每页显示7条数据
    current_page = int(request.GET.get("page", 1))  # 没有page这个key,就设置为1

# 这里是保证当前最多只显示11个页码
    if paginator.num_pages > 11:
        if current_page-5<1:
            page_range = range(1,12)
        elif current_page+5>paginator.num_pages:
            page_range = range(paginator.num_pages-10,paginator.num_pages+1)
        else:
            page_range = range(current_page - 5, current_page + 6)
    else:
        page_range = paginator.page_range

    # 显示当前页的book对象列表
    try:
        current_page_contents = paginator.page(current_page)
    #     如果数据为空,显示第一页的数据
    except EmptyPage as e:
        current_page_contents = paginator.page(1)

    return render(request, "index.html",locals())

index.html




    
    
    
     
    
    


    {% for book_obj in current_page_contents %}
  • {{ book_obj.title }}--{{ book_obj.price }}
  • {% endfor %}

6.分页,form组件
6.分页,form组件
6.分页,form组件

2.forms组件

作用:
主要是校验字段功能

2.1简单form

注意:
1.即使不是所有字段验证通过,form.cleaned_data中也有通过验证的字段的值。
2.前端传过来的字段可以比UserForm中的字段多,多余的字段不进行验证。所有字段验证通过,form.is_valid()返回true。
3.前端传过来的字段比UserForm中的字段少,form.is_valid()返回false。

forms.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from django import forms
class UserForm(forms.Form):
    name = forms.CharField(min_length=4, label="用户名", error_messages={"required": "该字段不能为空"})
    pwd = forms.CharField(min_length=4, label="密码", error_messages={"required": "该字段不能为空"})
    r_pwd = forms.CharField(min_length=4, label="确认密码", error_messages={"required": "该字段不能为空"})
    email = forms.EmailField(label="邮箱" , error_messages={"required": "该字段不能为空", "invalid": "格式错误"})
    tel = forms.CharField(label="手机号")

views.py

from django.shortcuts import render,HttpResponse
from django.core.paginator import Paginator,EmptyPage
from app1.models import *
from app1.myforms import *
def index(request):
    if request.method=="POST":
        print(request.POST)  # 
        form = UserForm(request.POST)
        if form.is_valid():
            print("form.cleaned_data----", form.cleaned_data)
        else:
            print("form.cleaned_data----", form.cleaned_data)  # {'pwd': '1234', 'email': '123@qq.com', 'tel': '123'}
            print("form.errors----", form.errors)
            print("type(form.errors)----", type(form.errors))  # 
            print("form.errors.get('name')----", form.errors.get("name"))  # 
  • 该字段不能为空
print("type(form.errors.get('name'))----", type(form.errors.get("name"))) # print("form.errors.get('name')[0]----", form.errors.get("name")[0]) return render(request, "index.html", locals())

index.html




    
    
    
     
    
    


简单form

{% csrf_token %}

6.分页,form组件
6.分页,form组件

2.2form三种渲染方式

forms.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from django import forms
from django.forms import widgets

class UserForm(forms.Form):
    # 自定义html中的标签和添加类
    name = forms.CharField(min_length=4, label="用户名", error_messages={"required": "该字段不能为空"},widget=widgets.TextInput(attrs={"class": "form-control"}))
    pwd = forms.CharField(min_length=4, label="密码", error_messages={"required": "该字段不能为空"},widget=widgets.PasswordInput(attrs={"class": "form-control"}))
    r_pwd = forms.CharField(min_length=4, label="确认密码", error_messages={"required": "该字段不能为空"},widget=widgets.PasswordInput(attrs={"class": "form-control"}))
    email = forms.EmailField(label="邮箱", error_messages={"required": "该字段不能为空", "invalid": "格式错误"},widget=widgets.EmailInput(attrs={"class": "form-control"}))
    tel = forms.CharField(label="手机号", widget=widgets.TextInput(attrs={"class": "form-control"}))

views.py

from django.shortcuts import render,HttpResponse
from django.core.paginator import Paginator,EmptyPage
from app1.models import *
from app1.myforms import *
def index(request):
    form = UserForm()
    if request.method=="POST":
        print(request.POST)  # 
        form = UserForm(request.POST)
        if form.is_valid():
            print("form.cleaned_data----", form.cleaned_data)
        else:
            print("form.cleaned_data----", form.cleaned_data)  # {'pwd': '1234', 'email': '123@qq.com', 'tel': '123'}
            print("form.errors----", form.errors)
            print("type(form.errors)----", type(form.errors))  # 
            print("form.errors.get('name')----", form.errors.get("name"))  # 
  • 该字段不能为空
print("type(form.errors.get('name'))----", type(form.errors.get("name"))) # print("form.errors.get('name')[0]----", form.errors.get("name")[0]) return render(request, "index.html", locals())

2.2.1渲染方式1

index.html




    
    
    
     
    
    


form组件渲染方式1

{% csrf_token %}
{{ form.name }} {{ form.name.errors.0 }}
{{ form.pwd }} {{ form.pwd.errors.0 }}
{{ form.r_pwd }} {{ form.r_pwd.errors.0 }}
{{ form.email }} {{ form.email.errors.0 }}
{{ form.tel }} {{ form.tel.errors.0 }}

6.分页,form组件
6.分页,form组件

2.2.2渲染方式2

index.html




    
    
    
     
    
    


form组件渲染方式2

{% csrf_token %} {% for field in form %}
{{ field }}
{% endfor %}

6.分页,form组件
6.分页,form组件

2.2.3渲染方式3

index.html




    
    
    
     
    
    


form组件渲染方式3

{% csrf_token %} {{ form.as_p }}

6.分页,form组件
6.分页,form组件

2.3form组件局部钩子

# 局部钩子函数名为clean_UserForm中字段名
# 返回值为val,报错时raise ValidationError("用户名长度最长为12")
# 错误信息存放在form.errors.get("字段名")[0]
def clean_name(self):
        val = self.cleaned_data.get("name")
        if len(val)<12:
            return val
        else:
            raise ValidationError("用户名长度最长为12")

查看源码

form.is_valid()

    def is_valid(self):
        """Return True if the form has no errors, or False otherwise."""
        return self.is_bound and not self.errors

        @property
    def errors(self):
        """Return an ErrorDict for the data provided for the form."""
        if self._errors is None:
            self.full_clean()
        return self._errors

    def full_clean(self):
        """
        Clean all of self.data and populate self._errors and self.cleaned_data.
        """
        self._errors = ErrorDict()
        if not self.is_bound:  # Stop further processing.
            return
        self.cleaned_data = {} # 是一个字典
        # If the form is permitted to be empty, and none of the form data has
        # changed from the initial data, short circuit any validation.
        if self.empty_permitted and not self.has_changed():
            return

        self._clean_fields() #局部钩子所在源码处,先执行局部钩子函数,然后执行全局钩子函数
        self._clean_form() #全局钩子所在源码处
        self._post_clean()

    def _clean_fields(self):
        for name, field in self.fields.items():
            # value_from_datadict() gets the data from the data dictionaries.
            # Each widget type knows how to retrieve its own data, because some
            # widgets split data over several HTML fields.
            if field.disabled:
                value = self.get_initial_for_field(field, name)
            else:
                value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
            try:
                if isinstance(field, FileField):
                    initial = self.get_initial_for_field(field, name)
                    value = field.clean(value, initial)
                else:
                    value = field.clean(value)
                self.cleaned_data[name] = value #可以看到,验证通过的字段赋值给了cleaned_data.
                if hasattr(self, 'clean_%s' % name):
                    value = getattr(self, 'clean_%s' % name)()
                    self.cleaned_data[name] = value
            except ValidationError as e:
                self.add_error(name, e)

6.分页,form组件

2.3.1局部钩子案例

forms.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
class UserForm(forms.Form):
    # 自定义html中的标签和添加类
    name = forms.CharField(min_length=4, label="用户名", error_messages={"required": "该字段不能为空"},widget=widgets.TextInput(attrs={"class": "form-control"}))
    pwd = forms.CharField(min_length=4, label="密码", error_messages={"required": "该字段不能为空"},widget=widgets.PasswordInput(attrs={"class": "form-control"}))
    r_pwd = forms.CharField(min_length=4, label="确认密码", error_messages={"required": "该字段不能为空"},widget=widgets.PasswordInput(attrs={"class": "form-control"}))
    email = forms.EmailField(label="邮箱", error_messages={"required": "该字段不能为空", "invalid": "格式错误"},widget=widgets.EmailInput(attrs={"class": "form-control"}))
    tel = forms.CharField(label="手机号", widget=widgets.TextInput(attrs={"class": "form-control"}))

# 局部钩子函数,必须是clean_字段名
    def clean_tel(self):
        val = self.cleaned_data.get("tel")
        if len(val)==11:
            return val
        else:
            raise ValidationError("手机格式错误")

    def clean_name(self):
        val = self.cleaned_data.get("name")
        if len(val)<12:
            return val
        else:
            raise ValidationError("用户名长度最长为12")

views.py

from django.shortcuts import render,HttpResponse
from django.core.paginator import Paginator,EmptyPage
from app1.models import *
from app1.myforms import *
def index(request):
    form = UserForm()
    if request.method=="POST":
        print(request.POST)  # 
        form = UserForm(request.POST)
        if form.is_valid():
            print("form.cleaned_data----", form.cleaned_data)
        else:
            print("form.cleaned_data----", form.cleaned_data)  # {'pwd': '1234', 'email': '123@qq.com', 'tel': '123'}
            print("form.errors----", form.errors)
            print("type(form.errors)----", type(form.errors))  # 
            print("form.errors.get('name')----", form.errors.get("name"))  # 
  • 该字段不能为空
print("type(form.errors.get('name'))----", type(form.errors.get("name"))) # print("form.errors.get('name')[0]----", form.errors.get("name")[0]) return render(request, "index.html", locals())

index.html




    
    
    
     
    
    


forms组件渲染方式1

{% csrf_token %}

{{ form.name.label }} {{ form.name }} {{ form.name.errors.0 }}

{{ form.pwd.label }} {{ form.pwd }} {{ form.pwd.errors.0 }}

确认密码 {{ form.r_pwd }} {{ form.r_pwd.errors.0 }}{{ errors.0 }}

邮箱 {{ form.email }} {{ form.email.errors.0 }}

手机号 {{ form.tel }} {{ form.tel.errors.0 }}

6.分页,form组件
6.分页,form组件

2.4form组件全局钩子

    # 全局钩子,函数名必须为clean
    # 返回值是self.cleaned_data,报错时raise ValidationError("两次密码不一致")
    # 错误信息存放在errors = form.errors.get("__all__").[0]
    def clean(self):
        pwd = self.cleaned_data.get("pwd")
        r_pwd=self.cleaned_data.get("r_pwd")
        # 当密码验证不通过的时候,假如密码pwd为空,就不要验证密码是否一致了
        if pwd and r_pwd:
            if pwd==r_pwd:
                return self.cleaned_data
            else:
                raise ValidationError("两次密码不一致")
        else:
            return self.cleaned_data

全局钩子源码

    def _clean_form(self):
        try:
            cleaned_data = self.clean()
        except ValidationError as e:  #这里捕获ValidationError,所以自己定义的函数中抛出该异常
            self.add_error(None, e)
        else:
            if cleaned_data is not None:
                self.cleaned_data = cleaned_data

    def clean(self):
        """
        Hook for doing any extra form-wide cleaning after Field.clean() has been
        called on every field. Any ValidationError raised by this method will
        not be associated with a particular field; it will have a special-case
        association with the field named '__all__'.
        """
        return self.cleaned_data   #所以我们重写clean方法,返回值为cleaned_data

6.分页,form组件

2.4.1全局钩子案例

forms.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
class UserForm(forms.Form):
    # 自定义html中的标签和添加类
    name = forms.CharField(min_length=4, label="用户名", error_messages={"required": "该字段不能为空"},widget=widgets.TextInput(attrs={"class": "form-control"}))
    pwd = forms.CharField(min_length=4, label="密码", error_messages={"required": "该字段不能为空"},widget=widgets.PasswordInput(attrs={"class": "form-control"}))
    r_pwd = forms.CharField(min_length=4, label="确认密码", error_messages={"required": "该字段不能为空"},widget=widgets.PasswordInput(attrs={"class": "form-control"}))
    email = forms.EmailField(label="邮箱", error_messages={"required": "该字段不能为空", "invalid": "格式错误"},widget=widgets.EmailInput(attrs={"class": "form-control"}))
    tel = forms.CharField(label="手机号", widget=widgets.TextInput(attrs={"class": "form-control"}))

    def clean_tel(self):
        val = self.cleaned_data.get("tel")
        if len(val)==11:
            return val
        else:
            raise ValidationError("手机格式错误")

    def clean_name(self):
        val = self.cleaned_data.get("name")
        if len(val)<12:
            return val
        else:
            raise ValidationError("用户名长度最长为12")

    # 全局钩子,函数名必须为clean
    def clean(self):
        pwd = self.cleaned_data.get("pwd")
        r_pwd=self.cleaned_data.get("r_pwd")
        # 当密码验证不通过的时候,假如密码pwd为空,就不要验证密码是否一致了
        if pwd and r_pwd:
            if pwd==r_pwd:
                return self.cleaned_data
            else:
                raise ValidationError("两次密码不一致")
        else:
            return self.cleaned_data

vews.py

from django.shortcuts import render,HttpResponse
from django.core.paginator import Paginator,EmptyPage
from app1.models import *
from app1.myforms import *
def index(request):
    form = UserForm()
    if request.method=="POST":
        print(request.POST)  # 
        form = UserForm(request.POST)
        if form.is_valid():
            print("form.cleaned_data----", form.cleaned_data)
        else:
            print("form.cleaned_data----", form.cleaned_data)  # {'pwd': '1234', 'email': '123@qq.com', 'tel': '123'}
            print("form.errors----", form.errors)
            print("type(form.errors)----", type(form.errors))  # 
            print("form.errors.get('name')----", form.errors.get("name"))  # 
  • 该字段不能为空
print("type(form.errors.get('name'))----", type(form.errors.get("name"))) # print("form.errors.get('name')[0]----", form.errors.get("name")[0]) errors = form.errors.get("__all__") print("errors----", errors) #
  • 两次密码不一致
print("type(errors)----", type(errors)) # return render(request, "index.html", locals())

index.html




    
    
    
     
    
    


forms组件渲染方式1

{% csrf_token %}

{{ form.name.label }} {{ form.name }} {{ form.name.errors.0 }}

{{ form.pwd.label }} {{ form.pwd }} {{ form.pwd.errors.0 }}

确认密码 {{ form.r_pwd }} {{ form.r_pwd.errors.0 }}{{ errors.0 }}

邮箱 {{ form.email }} {{ form.email.errors.0 }}

手机号 {{ form.tel }} {{ form.tel.errors.0 }}

6.分页,form组件
6.分页,form组件


本文标题:6.分页,form组件
文章链接:http://scyanting.com/article/jjgecd.html