django自带的序列化组件

2023-11-03

目录

sweetalert前端插件

django自带的序列化组件

简易分页器

带有页码的分页器

优化后的版本

模块代码

后端代码

Forms组件

校验数据

渲染标签

展示信息

 widgets

注意:


sweetalert前端插件

https://github.com/lipis/bootstrap-sweetalert

django自带的序列化组件

以后我们用的序列化组件是DRF

关键模块

from django.core import serializers

作用>>>>把数据序列化成我们需要的格式

使用

	from django.core import serializers
    def data_json(request):
        data = models.Book.objects.all()
        data_json = serializers.serialize('json',data)  #把QuerySet序列化成JSON格式
        return HttpResponse(data_json)


批量数据处理
'''
主要用来优化大批次数据的数据库操作,提高效率
'''
	def data_batch(request):
        # 1.定义空列表
        data_list = []
        # 2.把数据添加到列表中
        for i in range(1,10000):
            # 获取数据对象
            book_obj = models.Book(title=f'第{i}本书',price=100,stock=1000,sales=1000)
            # 数据对象添加到列表
            data_list.append(book_obj)
        # 3.执行批量操作
        models.Book.objects.bulk_create(data_list)
        return HttpResponse('ok')
分页器推导流程
"""
当数据量非常大时,我们一个页面展示不完,所以就创造了分页器
django本身也自带了一个分页器 只是不好用 所以我们自己写!!!
"""

简易分页器

def my_pager(request):
    # 获取页码
    current_page = request.GET.get('page')
    if not request.GET.get('page'):
        current_page = 1
    # 准备数据参数(以每页十条数据为准)
    start_num = (int(current_page)-1)*10
    end_num = start_num+10
    # 获取切片数据
    data_slice = models.Book.objects.all()[start_num:end_num]
    return render(request,'data_list.html',locals())

'''
通过控制url的pege参数就可以实现分页
'''

带有页码的分页器

def page(request):
    # 准备分页数据
    try:
        current_page = int(request.GET.get('page'))
    except Exception:
        current_page = 1
    # 准备数据参数(以每页十条数据为准)
    start_num = (current_page - 1) * 10
    end_num = start_num + 10
    # 获取切片数据
    data_slice = models.Book.objects.all()[start_num:end_num]
    # 获取数据总条数
    data_num = models.Book.objects.all().count()
    # 获取应该要多少页(以十条每页为标准)
    page_num,more = divmod(data_num,10)
    if more:
        page_num+=1  # 如果有余数,就要多来一页
    # 生成标签
    html = ''
    for i in range(1,page_num+1):
        html +='<li><a href="?page=%s">%s</a></li>'%(i,i)
    return render(request,'data_list.html',locals())

优化后的版本

def pager(request):
    # 准备分页数据
    try:
        current_page = int(request.GET.get('page'))
    except Exception:
        current_page = 1
    # 准备数据参数(以每页十条数据为准)
    start_num = (current_page - 1) * 10
    end_num = start_num + 10
    # 获取切片数据
    data_slice = models.Book.objects.all()[start_num:end_num]
    # 获取数据总条数
    data_num = models.Book.objects.all().count()
    # 获取应该要多少页(以十条每页为标准)
    page_num,more = divmod(data_num,10)
    if more:
        page_num+=1  # 如果有余数,就要多来一页
    # 生成标签
    html = ''
    start_page_num = current_page-5  # 起始显示页码
    end_page_num = current_page+6  # 终止显示页码
    if start_page_num<1:
        start_page_num = 1
    if end_page_num >page_num:
        end_page_num = page_num
    for i in range(start_page_num,end_page_num):
        if current_page == i:
            html += '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
            continue
        html +='<li><a href="?page=%s">%s</a></li>'%(i,i)
    return render(request,'data_list.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)
 '''
 创建utils文件夹
 在utils中创建一个py文件并将代码复制进去
 需要使用的地方导模块
 '''

后端代码

	def pager_model(request):
        # 获取数据对象
        data_queryset = models.Book.objects.all()
        # 创建分页器对象
        from utils import mypage
        pager_obj = mypage.Pagination(current_page=request.GET.get('page'),all_count=data_queryset.count(),per_page_num=10)
        # 产生分页对象
        page_queryset = data_queryset[pager_obj.start:pager_obj.end]
        return render(request,'pager.html',locals())

Forms组件

作用>>>>可以一次性帮我们实现数据校验,标签渲染,信息展示三步操作

使用

	# 创建Forms类
    from django import forms
    class Froms(forms.Form):
        username = forms.CharField(max_length=32)  # 最大长度32
        ags = forms.IntegerField(min_value=0,max_value=100)  # 最大为100,最小为0
        email = forms.EmailField()  # 必须是邮箱格式

校验数据

#1.实例化Forms对象
    from app01 import views
    form_obj =MyForm({'username':'petter','age':18,'email':'123456'})
#2.执行校验方法
    form_obj.is_valid()
        TRUE:结果全部合法
        FALSE:结果中有不合法的
#3.查看不合法数据及其原因
	form_obj.errors
		{'email': ['Enter a valid email address.']}
#4.查看符合条件的数据
    form_obj.cleaned_data
        {'username': 'petter', 'age': 18}

"""
1.forms类中所有的字段数据默认都是必填的 不能少
	如果想忽略某些字段 可以添加	required=False
2.forms类中额外传入的字段数据不会做任何的校验 直接忽略
"""

渲染标签

渲染方式1:封装程度高 扩展性较差 主要用于快速生成页面测试功能
	{{ form_obj.as_p }}  # 竖向
  {{ form_obj.as_table }}  # 横向
  {{ form_obj.as_ul }}  # 竖向加点

渲染方式2:封装程度低 扩展性较好 但是字段比较多的情况下不方便
  {{ form_obj.username.label }}  # 文本提示
  {{ form_obj.username }}	# 获取用户数据的标签
    
渲染方式3:推荐使用!!!
  {% for form in form_obj %}
      <p>
        {{ form.label }}
        {{ form }}
      </p>
  {% endfor %}

"""
forms组件只负责渲染获取用户数据的标签
	form表单标签和提交按钮需要自己写

渲染标签中文提示 可以使用参数 label指定 不指定默认使用字段名首字母大写
"""

展示信息

forms类中填写的校验性参数前端浏览器会识别并添加校验操作
但是前端的校验是可有可无的 不能指望它!!!   后端必须要有

form表单可以取消浏览器自动添加校验功能的操作
	<form action="" method="post" novalidate></form>
"""
{{ form.errors.0 }}

提示信息可以自定义
	username = forms.CharField(min_length=3,max_length=8,label='用户名',
               error_messages={
                         'min_length':'用户名最短3位',
                          'max_length':'用户名最长8位',
                          'required':'用户名必填'
                               })

 widgets

是用来引入bootstrap样式的。


register.html

<div class="container">
    <h1 class="text-center">注册功能</h1>
    <div class="row">
        <div class="col-md-4 col-md-offset-4">
            <form action="" method="post" novalidate>
                {% for foo in form_obj %}
                    <p>
                        <label for="">{{ foo.label }}</label>
                        {{ foo }}<span style="color: red">{{ foo.errors.0 }}</span>
                    </p>
                {% endfor %}
                <input type="submit" value="提交" class="btn btn-success">
            </form>
        </div>
    </div>
</div>

views.py

from django import forms  # 引入forms组件
from django.forms import widgets


class UserForm(forms.Form):  # 必须继承forms.Form
    # forms.CharField和forms.EmailField会渲染为input标签
    name = forms.CharField(min_length=3, max_length=8, label='用户名',
                           error_messages={'required': '用户名不能为空'},
                           widget=widgets.TextInput(attrs={'class': 'form-control'})
                           )
    pwd = forms.CharField(min_length=3, max_length=8, label='密码',
                          widget=widgets.PasswordInput(attrs={'class': 'form-control'})  # 密文文本输入框
                          )
    re_pwd = forms.CharField(min_length=3, max_length=8, label='确认密码',
                             widget=widgets.PasswordInput(attrs={'class': 'form-control'})
                             )
    email = forms.EmailField(label='邮箱', error_messages={'required': '邮箱地址不能为空', 'invalid': '格式错误'},
                             widget=widgets.EmailInput(attrs={'class': 'form-control'})
                             )
    phone = forms.CharField(min_length=11, max_length=11, error_messages={'required': '手机号不能为空'},
                            widget=widgets.TextInput(attrs={'class': 'form-control'})                         )

 

注意:

  1. 在字段构造中设置error_messages参数修改字段错误信息提示:其中required表示字段不能为空的提示,invalid表示字段格式错误的提示信息。
  2. 在字段构造函数中配置input类型:设置为文本域、密码域、单选框、复选框等等类型。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

django自带的序列化组件 的相关文章

随机推荐

  • ubuntu安装flex和bison时显示没有可安装候选的解决方案

    任务 在ubuntu虚拟机中下载安装flex和bison 工具版本 Virtual Box6 1 Ubuntu16 BUG描述 输入命令 sudo apt get install flex bison 报错 解决方案 flex和bison属
  • Set构造函数及其属性

    Set构造函数及其属性 Set的属性 Set prototype Set prototype add 方法 Set prototype clear 方法 Set prototype has 方法 Set prototype delete 方
  • UART串口的8倍过采样和16倍过采样原理

    由于在空闲状态时 传送线为逻辑 1 状态 而数据的传送总是以一个起始位 0 开始 所以当接收器检测到一个从 1 向 0 的跳变时 便视为可能的起始位 要排除干扰引起的跳变 起始位被确认后 就知道发送器已开始发送 接收器就可以按这个数据通信格
  • 利用SSM搭建web项目

    下面给大家介绍一下 ssm的搭建和使用 7步搞定框架搭建 SSM所需要的jar包下载地址 http download csdn net download baidu 32492845 10126554 1 创建数据库 DROP TABLE
  • 性能测试怎么做?性能测试策略配套适用场景,打通性能测试...

    目录 导读 前言 一 Python编程入门到精通 二 接口自动化项目实战 三 Web自动化项目实战 四 App自动化项目实战 五 一线大厂简历 六 测试开发DevOps体系 七 常用自动化测试工具 八 JMeter性能测试 九 总结 尾部小
  • 网易2018校园招聘编程题真题集合

    1 8 编程题 魔法币 include
  • linux fedora 桌面环境,为Fedora 30系统安装Deepin桌面环境(DDE)

    Fedora 30已经新增两个桌面环境选项 DeepinDE 和 Pantheon Desktop 所以除GNOME KDE Plasma 和 Xfce 之外 因为Deepin桌面环境现在可以在Fedora 30存储库中使用 用户现在还可以
  • ChatGPT应用场景: 基于对话生成的智能客服系统

    关于ChatGPT 今天小编简单说下用在客服服务的要点 ChatGPT可以用于开发基于对话生成的智能客服系统 帮助企业提供高效 便捷 满意的在线客服服务 从而提升客户体验和满意度 以下是ChatGPT应用于智能客服系统的一些场景 1 自动回
  • 基于redis分布式缓存实现

    在网上找了些redis搭建集群的资料 分享给大家 可以仔细看看 了解redis主从复制的逻辑 以及如何构建redis集群 Redis复制流程概述 Redis的复制功能是完全建立在之前我们讨论过的基于内存快照的持久化策略基础上的 也就是说无论
  • flask.ext 的那些事

    偶然发现 在pycharm 使用alter enter 自动修复 未导入的外部模块时 推荐的是 flask ext 包名 的形式 如下例 from flask ext migrate import Migrate MigrateComman
  • 分立元件搭建自举电路解析-高端mos驱动

    分立元件搭建自举电路 上桥mos驱动 高端MOS为什么要自举电路 自举电容 分立元件搭建自举电路 高端MOS为什么要自举电路 众所周知MOS是电压型驱动 只有G极比S极高一个开启电压Vth之后 MOS才会导通 这里指NMOS 但是如下图 我
  • JQuery 页面加载完成后执行事件

    一 document ready function code 二 jQuery document ready function code 三 window nl ad function code 四 将jquery代码放入body的后面 这
  • 使用OpenCV/python进行双目测距

    在做SLAM时 希望用到深度图来辅助生成场景 所以要构建立体视觉 在这里使用OpenCV的Stereo库和python来进行双目立体视觉的图像处理 立体标定 应用标定数据 转换成深度图 标定 在开始之前 需要准备的当然是两个摄相头 根据你的
  • 什么是 agent

    agent 是任何通过sensor感知其环境并通过actuators在此环境中作出行动的东西 比如人agent sensor 是眼睛 耳朵 以及其他器官 actuators 是手 腿 声道等 比如机器人agent sensor 是摄像头 红
  • JVM系列-第8章-执行引擎

    文章目录 toc 执行引擎 执行引擎概述 执行引擎概述 执行引擎工作过程 Java代码编译和执行过程 解释执行和即时编译 什么是解释器 什么是JIT编译器 机器码 指令 汇编语言 机器码 指令和指令集 汇编语言 高级语言 字节码 C C 源
  • Java使用图片压缩工具压缩图片的两种方法

    上代码 pom xml
  • 单元测试是什么?为什么要做单元测试?

    背锅侠 一个有个性的订阅号 1 单元测试是什么 单元测试是开发者编写的一小段代码 用于检验被测代码的一个很小的 很明确的功能是否正确 通常而言 一个单元测试是用于判断某个特定条件 或者场景 下某个特定函数的行为1 长按图片识别二维码 入群
  • [Qt 教程之Widgets模块] —— QButtonGroup抽象容器

    Qt系列教程总目录 文章目录 0 QButtonGroup简介 1 创建QButtonGroup 2 成员函数与信号 3 示例 3 1 为按钮组添加按钮 3 2 为按钮设置id 3 3 按钮组中按钮的互斥状态 3 4 获取组内所有按钮 3
  • 开源图像和视频编辑软件汇总

    1 Belender http www blender org Blender 是一套 三维绘图 及 渲染 软件 它具有跨平台的特性 支持 FreeBSD IRIX GNU Linux Microsoft Windows Mac OS X
  • django自带的序列化组件

    目录 sweetalert前端插件 django自带的序列化组件 简易分页器 带有页码的分页器 优化后的版本 模块代码 后端代码 Forms组件 校验数据 渲染标签 展示信息 widgets 注意 sweetalert前端插件 https