Django—分页器与form组件

目录

  • 分页器

    • 现成分页器代码
    • 如何使用
      • 后端
      • 前端
  • form组件
    • form 校验组件

      • 使用校验组件与钩子函数
    • 三种渲染方式
    • 正则校验*

分页器

现成分页器代码

只需要会使用即可。

在Django项目下新建utils文件夹,新建一个py文件,放入封装好的分页器代码。

class Pagination(object):
    def __init__(self, current_page, all_count, per_page_num=10, pager_count=11):
        """
        封装分页相关数据
        :param current_page: 当前页
        :param all_count:    数据库中的数据总条数
        :param per_page_num: 每页显示的数据条数
        :param pager_count:  最多显示的页码个数

        用法:
        queryset = model.objects.all()
        page_obj = Pagination(current_page,all_count)
        page_data = queryset[page_obj.start:page_obj.end]
        获取数据用page_data而不再使用原始的queryset
        获取前端分页样式用page_obj.page_html
        """
        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1

        if current_page < 1:
            current_page = 1

        self.current_page = current_page

        self.all_count = all_count
        self.per_page_num = per_page_num

        # 总页码
        all_pager, tmp = divmod(all_count, per_page_num)
        if tmp:
            all_pager += 1
        self.all_pager = all_pager

        self.pager_count = pager_count
        self.pager_count_half = int((pager_count - 1) / 2)

    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_num

    @property
    def end(self):
        return self.current_page * self.per_page_num

    def page_html(self):
        # 如果总页码 < 11个:
        if self.all_pager <= self.pager_count:
            pager_start = 1
            pager_end = self.all_pager + 1
        # 总页码  > 11
        else:
            # 当前页如果<=页面上最多显示11/2个页码
            if self.current_page <= self.pager_count_half:
                pager_start = 1
                pager_end = self.pager_count + 1

            # 当前页大于5
            else:
                # 页码翻到最后
                if (self.current_page + self.pager_count_half) > self.all_pager:
                    pager_end = self.all_pager + 1
                    pager_start = self.all_pager - self.pager_count + 1
                else:
                    pager_start = self.current_page - self.pager_count_half
                    pager_end = self.current_page + self.pager_count_half + 1

        page_html_list = []
        # 添加前面的nav和ul标签
        page_html_list.append('''
                    <nav aria-label='Page navigation>'
                    <ul class='pagination'>
                ''')
        first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
        page_html_list.append(first_page)

        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
        else:
            prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)

        page_html_list.append(prev_page)

        for i in range(pager_start, pager_end):
            if i == self.current_page:
                temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
            else:
                temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
            page_html_list.append(temp)

        if self.current_page >= self.all_pager:
            next_page = '<li class="disabled"><a href="#">下一页</a></li>'
        else:
            next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
        page_html_list.append(next_page)

        last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
        page_html_list.append(last_page)
        # 尾部添加标签
        page_html_list.append('''
                                           </nav>
                                           </ul>
                                       ''')
        return ''.join(page_html_list)

如何使用

后端

class Books(View):
    def get(self, request):
        book_queryset = models.Book.objects.all()  # 获取所有书籍对象
        current_page = request.GET.get('page', 1)  # 获得当前页码,如果没有就为1
        book_count = book_queryset.count()  # 获取数据总条数

        # 1 分页器类实例化出对象
        page_obj = Pagination(per_page_num=12, current_page=current_page, all_count=book_count)
        # 2 对数据进行切片操作,每页展示
        page_queryset = book_queryset[page_obj.start:page_obj.end]

        return render(request, 'Books.html', locals())

前端

{% for foo in page_queryset %}
<p>{{ foo.title }}</p>
{% endfor %}

{{ page_obj.page_html|safe }}

form组件

form 校验组件

校验数据通常是前后端都校验,但是前端校验可有可无,后端必须校验

注册功能需求:
用户输入的用户名种不能包含‘虫合’,不可小于三位,不可大于八位
    如果包含了,就提示用户---》太暴力了
用户输入的密码,不可小于三位,不可大于八位
    太短太长都提示

搭建步骤:
    1.搭建前端页面                                  >>>                渲染页面
    2.获取前端用户提交的数据校验                       >>>                校验数据
    3.对数据的校验的结果 展示到前端页面给用户查看         >>>            展示错误信息

 form组件能够自动帮你完成上面的三件事

使用校验组件与钩子函数

# 1 自己先写一个类
# 像创建表一样规定了各个输入框需要遵守的规则,以及违反对应规则会抛出的错误
class Myform(forms.Form):
    username = forms.CharField(max_length=8, min_length=3, error_messages={
        'min_length': '你太短了',
        'max_length': '你太长了',
        'required': '不可为空'
    }, initial='我是初始值', widget= widgets.TextInput(attrs={'class':'form-control others'})#为这个input标签添加了一个类,用attr={}的方式设置
        #widget可以改变input框的type属性值

    pwd = forms.CharField(max_length=8, min_length=3, error_messages={
        'min_length': '你太短了',
        'max_length': '你太长了',
        'required': '不可为空'
    }, initial='我是初始值',widget=widgets.PasswordInput())

#2 后端代码
def reg(request):
    form_obj = Myform()#将自己写的类实例化出一个对象,若请求方式为get则不通过校验,直接将form_obj传到前端页面,提供渲染页面的功能

    if request.method=='POST':
        #由于request.POST本身就是个大字典,直接扔进去做校验
        form_obj=Myform(request.POST) 

        if form_obj.is_valid():
            #is_valid判断是否所有键值对都满足规则,只有都满足时is_valid才为真
            return HttpResponse('合法')

    return render(request,'reg.html',locals())

#3 前端代码
<form action="" method="post" novalidate>
#novalidate是告诉浏览器无需在浏览器做校验

{% for foo in form_obj %}
    <p>{{ foo.label }}: {{ foo }}</p>
    <span style="color: red">{{ foo.errors.0 }}</span>
    #foo.errors拿到的是列表的错误信息,取第一个直接拿出错误信息,如没有错误则为空
{% endfor %}
<input type="submit">

#局部钩子 校验用户输入的用户名种不得包含‘虫合’(写在自定的Myform类中)
    def clean_username(self):
        username = self.cleaned_data.get('username')
        #cleaned_data是一个字典,如果键值对经过之前的校验并通过了,就会放在这里面
        #与cleaned_data相反的是errors,也是字典,保存的是校验不通过的字段以及原因
        if '虫合' in username:
            # 给username字段下面提示错误信息
            self.add_error('username', '太暴力了')
        return self.cleaned_data
        #return username

#全局钩子 校验用户名与密码不得相同
    def clean(self):
        username=self.cleaned_data.get('username')
        pwd=self.cleaned_data.get('pwd')
        if pwd==username:
            self.add_error('pwd','密码不得与用户名相同')
        return self.cleaned_data
        #return pwd

三种渲染方式

如何渲染页面
    1.forms组件只会帮你渲染获取用户输入(输入,选择,下拉框...)的标签  提交按钮需要你自己手动写

    <p>三种渲染前端页面的方式</p>
    <p>第一种渲染前端页面的方式:封装程度太高了 标签样式及参数不方便调整 可扩展性差(不推荐使用)
    {{ form_obj.as_p }}
    {{ form_obj.as_ul }}
    </p>

    <p>第二种渲染页面的方式:扩展性较高 不足之处在于 需要你手写的代码量比较多(不推荐使用)</p>
    <p>
        {{ form_obj.username.label }}{{ form_obj.username }}
    </p>
    <p>
        {{ form_obj.password.label }}{{ form_obj.password }}
    </p>
    <p>
        {{ form_obj.email.label }}{{ form_obj.email }}
    </p>

    <p>第三种渲染前端页面的方式:代码量和扩展性都很高(推荐使用)</p>
    {% for foo in form_obj %}
    <p>{{ foo.label }}{{ foo }}</p>
    {% endfor %}

正则校验*

每个字段 还支持正则校验
    from django import forms
    from django.forms import Form
    from django.core.validators import RegexValidator

class MyForm(Form):
    user = forms.CharField(
        validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
    )

原文地址:https://www.cnblogs.com/Sheppard/p/11761298.html

时间: 2024-10-08 23:53:19

Django—分页器与form组件的相关文章

Django 框架篇(九): Django中的Form 组件

Django中的Form组件,帮我们处理了 form表单中的校验, 和错误提示的处理: 主要功能: 生成页面可用的HTML标签 对用户提交的数据进行校验 保留上次输入内容 使用form组件实现注册功能 1.  定义一个类, 继承django中的 forms.Form 代码实例: from django import forms # 按照Django form组件的要求自己写一个类 class RegForm(forms.Form): name = forms.CharField(label="用

Django框架之Form组件

新手上路 From组件的主要功能: 1,对form表单提交的数据进行校验. 内部基于正则进行匹配 2,from表单提交保存上次提交的数据. 生成HTML标签 初入大荒 1,创建Form类 class StudentForm(Form): #字段名,最好跟数据库内的字段名一样,好操作 #如CharField,内部包含了正则表达式, name = fields.CharField(max_length=12, min_length=2, required=True, widget=widgets.T

django补充和form组件

Model常用操作: - 参数:filter - all,values,values_list [obj(id,name,pwd,email),obj(id,name,pwd,email),] models.UserInfo.objects.all() [obj(id,name,email)] # pwd未取值 data_list = models.UserInfo.objects.all().only('name','email') for item in data_list: item.id

Django框架 之 form组件

浏览目录 Form介绍 普通的登录 使用form组件 Form详情 常用字段 校验 进阶 使用Django Form流程 一.Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确.如果用户输入的内容有错误就需要在页面上相应的位置显示显示对应的错误信息.. Django form组件就实现了上面所述的功能. 总结一下,其

Django框架 之 form组件的钩子

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 def foo(request):     if request.method=="POST":         regForm=Reg

用Django内置form组件实现注册

HTML页面代码块: 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 6 <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> 7 <title>首页</title&

Django ==&gt; Form 组件

Django ==> Form 组件 目录: 1.基本使用 2.form中字段和插件 3.自定义验证规则 4.动态加载数据到form中 Action: 1.基本使用 django 中的Form组件有一下功能: 1.生成html标签 2.验证用户数据(显示错误信息) 3.html form 提交保留上次提交数据 4.初始化页面显示内容 要使用 form 类,首先需要创建这个类,方法如下: from django.forms import Form from django.forms import

Django Form组件实例:登录界面[Form表单提交,Ajax提交]

"""本例中使用Form和Ajax进行了数据提交,Form提交有一个问题,就是输入错误的数据,刷新之后原有的数据会丢失.注意到Form组件可以生成HTML标签,将Form生成的对象传到前端,就可以保留原有的内容,具体见下文:""" 1 from django.shortcuts import * 2 from app02 import models 3 import json 4 5 # Create your views here. 6 def

Django【十三】form组件。

一.form组件 form组件的功能: 检验功能 前端生成HTML页面 还能保留输入的内容 form组件的用法: from django import forms # Create your views here. # 定义一个类 class Myform(forms.Form): title = forms.CharField( # 通过from表单进行验证的时候,验证输入title字段的数据,参数用于验证 max_length=20, min_length=2, ) # CharField/