ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

分页器与from组件分析

2022-09-08 23:30:37  阅读:232  来源: 互联网

标签:分析 obj 分页 form self current 组件 page name


分页器与from组件分析

批量操作数据

1.浏览器访问django路由,创建十万条数据存储到sqliet3数据库中并展示到前端页面(额,这个有点看电脑创建的多了,有可能数据库就崩了自己上锁了,看命)
    for i in range(100000):
        models.Book.objects.create(title=f'第{i}本书')
    book_query = models.Book.objects.all()
2.我们使用sqlite3数据库也需要下载配置文件,直接database点击download下载即可,可能会下的有点慢耐心等待即可
3.涉及到大批量数据的创建,直接使用create可能会造成数据库崩溃,所以就需要另辟蹊径
	批量数据创建	>>>:	bulk_create()
	批量数据修改	>>>:	bulk_update()
4.实现快速创建十万数据
def index(request):
    # for i in range(100000):
    #     models.Book.objects.create(title=f'第{i}本书')
    book_list = []
    for i in range(100000):
        book_obj = models.Book(title=f'第{i}本书')
        book_list.append(book_obj)
    # 简写版本(列表生成式):
    book_list = [models.Book(title=f'第{i}本书') for i in range(10000)]
    models.Book.objects.bulk_create(book_list)
    book_query = models.Book.objects.all()
    return render(request,'index.html',locals())

分页器推到流程

1.首先我们上面做到了将所有的书全部展示到页面,那么我们就应该将他进行分页处理,方便我们查看
2.使用QuerySet切片操作,然后我们就可以通过浏览器上方浏览到我们所切到的页数
3.优化上一步我们那样做太麻烦了,也不适用于大众所以我们要给它加上一个简易的分页器,所以我们就需要到Bootstrap上寻找一个分页器到html页面
4.然后绑定传输页面所需要的值,但是由于该模板页数过小我们就应该在他的基础上进行修改
5.我们需要使用for循环给它将地址循环出来,但是由于html前端不支持for循环那么我们就需要使用后端循环传给前端进行使用
6.我们就需要将前方的页码数据进行优化,使用divmod判断有多少个分组,如果有剩余那么分组加一
7.将分好组的按钮信息传入前端由前端展示,页码推荐使用奇数位,利用的那个钱页面固定位数来限制
8.但是我们会发现到一后还是会有负位按键,那么我们判断是否为1然后将位数固定在奇数位即可
9.将按钮显示在某页
def index(request):
    # for i in range(100000):
    #     models.Book.objects.create(title=f'第{i}本书')
    # book_list = []
    # for i in range(100000):
    #     book_obj = models.Book(title=f'第{i}本书')
    #     book_list.append(book_obj)
    # 简写版本(列表生成式):
    # book_list = [models.Book(title=f'第{i}本书') for i in range(10000)]
    # models.Book.objects.bulk_create(book_list)
    book_data = models.Book.objects.all()
    all_count = book_data.count()
    per_page_num = 10
    all_page_num, more = divmod(all_count,per_page_num)
    if more:
        all_page_num + 1
    current_page = request.GET.get('page', 1)
    try:
        current_page = int(current_page)
    except ValueError:
        current_page = 1
    html_page = ''
    now_page = current_page
    if current_page < 6:
        now_page = 6
    elif current_page >= all_page_num:
        now_page = all_page_num-4
    for i in range(now_page - 5,now_page + 6):
        if current_page == i:
            html_page += '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
        else:
            html_page += '<li><a href="?page=%s">%s</a></li>' % (i, i)
    # print('总页码:',all_page_num)
    start_num = (current_page-1) * per_page_num
    end_num = current_page * per_page_num
    book_query = models.Book.objects.all()[start_num:end_num]
    return render(request,'index.html',locals())

分页器模板

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

自定义分页器

1.我们也可以使用自定义分页器导入即可
2.后端配置
from app01.plugins import mypage
def get_book(request):
   book_list = models.Book.objects.all()
   current_page = request.GET.get("page",1)
   all_count = book_list.count()
   page_obj = Pagination(current_page=current_page,all_count=all_count,per_page_num=10)
   page_queryset = book_list[page_obj.start:page_obj.end]
   return render(request,'booklist.html',locals())
3.前端配置
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            {% for book in page_queryset %}
            <p>{{ book.title }}</p>
            {% endfor %}
            {{ page_obj.page_html|safe }}
        </div>
    </div>
</div>

form组件校验前戏

1.自己搓一个校验器
def ab_form(request):
    data_dict = {'username':'','password':''}
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'joseph':
            data_dict['username'] = 'joseph想去玩'
        if password == 520:
            data_dict['password'] = '520好想抱抱她'
    return render(request,'ab_form.html',locals())

form组件简介

form组件
	1.数据校验
		支持提前设置各种校验规则,之后自动校验
	2.渲染页面
		支持直接渲染获取用户数据的各种标签
	3.展示信息
		支持针对不同的校验失败展示不同的提示
        
form类型简单创建
from django import forms  # 导入forms模块


class MyForm(forms.Form):
    name = forms.CharField(max_length=24,min_length=2)  # 设置姓名最常为24个字符,最短为2个字符
    age = forms.IntegerField(max_value=180,min_value=0)  # 设置年龄最大为180岁,最小为0岁
    email = forms.EmailField()  # 邮箱必须符合邮箱格式(最少要带一个@符)

form组件校验数据

1.传递待校验数据
	 from app01 import views
    form_obj = views.MyForm({'name':'joseph','age': 21, 'email':520})
2.判断所有受是否符合校验
    form_obj.is_valid()
    False
3.获取符合校验规则的数据
    form_obj.cleaned_data
    {'name': 'joseph', 'age': 21}
4.获取不符合校验规则的数据以及错误的原因
    form_obj.errors
    {'email': ['Enter a valid email address.']}
5.正确数据
    form_obj = views.MyForm({'name':'joseph','age': 21, 'email':'520@qq.com'})
    form_obj.cleaned_data
6.额外数据
form_obj = views.MyForm({'name':'joseph','age': 21, 'email':'520@qq.com','hobby':'read'})
    form_obj.cleaned_data
7.特性
	form类中编写的字段默认是必填的,少传通不过校验,然而多传则不校验,全程忽略,我只想要我要的其他人都是空气

form组件渲染标签

1.注释分类
	{# 第一种注释,在浏览器页面看不到,是html自带的一种注释 #}
	<!--第二种注释,在浏览器页面可以看到-->
2.渲染标签功能
	方式一:(封装程度高,但是扩展性较差)
		{{ form_obj.as_p }}
		{{ form_obj.as_table }}
		{{ form_obj.as_ul }}
	方式二:(封装程度低,扩展性好,但是编写困难,麻烦)
		{{ form_obj.name.label }}
		{{ form_obj.name }}
		{{ form_obj.age.label }}
		{{ form_obj.age }}
		{{ form_obj.email.label }}
		{{ form_obj.email }}
	方式三:(推荐使用)
		{% for form in form_obj %}
			<p>{{ form.label }}{{ form }}</p>
		{% endfor %}

form组件展示信息

1.form表单如何取消浏览器自动添加的数据校验功能
		<form action="" method="post" novalidate>
   	{% for form in form_obj %}
        <p>
            {{ form.label }}{{ form }}
            <span style="color: red;">{{ form.errors.0 }}</span>
        </p>
    {% endfor %}
    <input type="submit" value="提交">

    def func(request):
        form_obj = MyForm()
        if request.method == 'POST':
            form_obj = MyForm(request.POST)
            if form_obj.is_valid():
                print(form_obj.cleaned_data)
        return render(request,'func.html',locals())
2.修改默认字符格式
	LANGUAGE_CODE = 'en-us'  # 英文
	from django.conf import global_settings  # 字符介绍地址
	('zh-hans', gettext_noop('Simplified Chinese')),  # 简体中文
	('zh-hant', gettext_noop('Traditional Chinese')),  # 繁体中文

form组件字段常见参数

字段参数 功能
max_length 最大位数
min_length 最小位数
max_value 最大值
min_value 最小值
label 字段注释
error-messages 错误提示
required 是否为空
widget 标签类型,标签属性
initial 默认值
validathors 正则校验

form组件钩子函数

提供自定义的校验方式
局部钩子:校验单个(局部)字段
	def clean_name(self):
		name = self.cleaned_data.get('name')
		res = models.User.objects.filter(name=name).first()
		if res:
			return self.add_error('name','用户名已存在')
		return name
全局钩子:校验多个字段
	def clean(self):
		pwd = self.cleaned_data.get('pwd')
		confirm_pwd = self.cleaned_data.get('confirm_pwd')
		if not pwd == confirm_pwd:
			return self.add_error('confirm_pwd','密码不一致')
		return self.cleaned_data

form组件源码分析

1.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
2.is_bound
	无论怎样都是空
	self.is_bound = data is not None or files is not None
3.errors
	def errors(self):
	"""Return an ErrorDict for the data provided for the form."""
		if self._errors is None:  # 前面带了下划线就是不想让你访问的,大家都墨守成规
			self.full_clean()
		return self._errors
4._errors
	self._errors = None  # Stores the errors after clean() has been called. 仅做展示是个空
5.full_clean
	def full_clean(self):  # 终于快到了
		self._clean_fields()
		self._clean_form()
		self._post_clean()
6._post_clean
	def _post_clean(self):  # 空
	"""
	An internal hook for performing additional cleaning after form cleaning
	is complete. Used for model validation in model forms.
	"""
		pass
7._clean_form
    def _clean_form(self):
        try:
            cleaned_data = self.clean()
        except ValidationError as e:
            self.add_error(None, e)
        else:
            if cleaned_data is not None:
                self.cleaned_data = cleaned_data
8._clean_fields
def _clean_fields(self):
	for name, field in self.fields.items():
		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
				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)

modelform组件

1.modelform是form的优化版本 使用更简单 功能更强大,底层也是使用面向对象反射与钩子函数

class MyModelForm(forms.ModelForm):
    class Meta:
        model = models.User
        fields = '__all__'
    def clean_name(self):
        name = self.cleaned_data.get('name')
        res = models.User.objects.filter(name=name).first()
        if res:
            self.add_error('name','用户名已存在')
        return name

标签:分析,obj,分页,form,self,current,组件,page,name
来源: https://www.cnblogs.com/joseph-bright/p/16671213.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有