5.20python笔记

django自带序列化组件、批量数据操作、分页器、forms组件

#sweetalert前端插件
	https://github.com/lipis/bootstrap-sweetalert

 
# 可用cdn:
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script> 

# 配置及方法
https://sweetalert.js.org/docs/
    
# 关键字
swal()  # 唤起弹窗关键字,可绑定点击事件

传参方式1:
swal("标题文本","正常文本","模态图标")
eg:
	swal("title","text","success")
传参方式2:
swal({
    title:"标题文本",
    text:"正常文本",
    icon:"success",
})

# 主要参数
1.text文本
text:"字符串类型的文本"
eg:
    swal({
        text: "Hello world!",
    });

2.title标题
title:"标题文本"
eg:
    swal({
        title: "Here's a title!",
    });
     
icon:"warning/error/success/info"  # 四个内置图标   
eg:
    swal({
        icon: "success",
    });

3.button单选按钮
button:{
  text: "OK",  # 按钮文字
  value: true,  
  visible: true,  # 为true时显示按钮,为false时隐藏
  className: "",  # 类名
  closeModal: true,  
}  # 按钮设置
button:"按钮名称"  # 可以直接创造一个按钮
eg:
    swal({
        button: "Coolio",
    });  # 直接设置一个按钮
    swal({
        button: {
            text: "Hey ho!",
            ...
        },
    });  # 按钮设置
    
4.buttons多选按钮    
buttons:{
  cancel: {
    text: "Cancel",
    value: null,
    visible: false,
    className: "",
    closeModal: true,
  },  # cancel按钮设置
  confirm: {
    text: "OK",
    value: true,
    visible: true,
    className: "",
    closeModal: true
  }  # confirm按钮设置
}
eg:
    swal({
        buttons: ["Stop", "Do it!"],
    });  # 直接设置取消和确定按钮
    
    swal({
        buttons: [true, "Do it!"],
    });  # 直接设置取消和确定按钮
    
    swal("Hello world!", {
        buttons: false,
    });  # 直接隐藏按钮
    
    swal({
        buttons: {
            cancel: true,  # 取消按钮
            confirm: true,  # 确认按钮
        },
    });  # 对按钮进行设置
    
    swal({
        buttons: {
            cancel: true,
            confirm: "Confirm",
            roll: {
                text: "Do a barrell roll!",
                value: "roll",
            },
        },
    });  # 设置三个按钮
    
5.content自定义文本或图标
eg:
    swal({
        content: "input",
    });  # 自定义文本,输入框
    
    swal({
        content: {
            element: "input",
            attributes: {
                placeholder: "Type your password",
                type: "password",
            },
        },
    });  # 自定义文本及文本类型,输入框
    
    var slider = document.createElement("input");
    slider.type = "range";

    swal({
        content: slider,
    });  # 自定义图标

6.classname类名
className:"red-bg"
eg:
    swal("Hello world!", {
        className: "red-bg",
    });  # 自定义类,可以改变外观
    
closeOnClickOutside
eg:
    swal({
      closeOnClickOutside: false,
    });
	# 决定用户是否可以通过在模态外面点击来关闭它

7.closeOnEsc, Esc键退出
closeOnEsc:true
eg:
    swal({
        closeOnEsc: false,
    });  # 决定用户是否可以通过按ESC键来解除模式

8.dangerMode设置危险操作按钮
dangerMode:true
eg:
    swal("Are you sure?", {
        dangerMode: true,
        buttons: true,
    });
	# 如果设置为true,确认按钮将变为红色,而默认焦点将设置在取消按钮上。 当确认操作是危险的(例如删除一个项目)时,这是很方便的。  

9.timer计时关闭模态框
timer:3000  # 单位毫秒
eg:
    swal("This modal will disappear soon!", {
        buttons: false,
        timer: 3000,  # 3秒后关闭
    });
	# 在一定时间(以毫秒为单位)后关闭模态,与按钮组合有用button:false
    
# 主要方法及主题等见配置网址
https://sweetalert.js.org/docs/

django自带的序列化组件

"""
以后我们用的序列化组件是DRF 这里学自带的是提前看一眼效果
"""

1.使用JsonResponse序列化
from app01 import models
from django.http import JsonResponse
def d_data(request):
    # 前后端分离之后 django orm产生的queryset无法直接被前端识别 还是需要json格式数据(硬通货)
    data_list = []  # [{}, {}, {}] 存储格式为列表套字典
    user_queryset = models.User.objects.all()
    for user_obj in user_queryset:  # for循环queryset获取每个对象,将数据添加到datalist
        data_list.append({
            'pk':user_obj.pk,
            'name':user_obj.name,
            'age':user_obj.age,
            'gender':user_obj.gender,
            'gender_real':user_obj.get_gender_display(),
            'addr':user_obj.addr
        })
    return JsonResponse(data_list,safe=False)  # 使用JsonResponse将datalist序列化返回前端

2.django自带的序列化组件:serializers
from app01 import models
from django.core import serializers
def d_data(request):
    user_queryset = models.User.objects.all()  # 先获取queryset,即所有记录对象
    ret = serializers.serialize('json', user_queryset)  # 左边参数是json格式,右边参数是queryset对象
    return HttpResponse(ret)  # 返回json对象到前端

批量数据操作

def many_data(request):
    '''普通批量插入:create'''
    # 循环插入10万条数据(频繁走数据库操作 效率极低 不推荐!!!)
    # for i in range(100000):
    #     models.Book.objects.create(title=f'第{i}本书')
    
    '''批量快速插入:bulk_create'''
    book_list = []  # 空列表用于存储批量数据
    for i in range(100000):
        # 先用类产生一个对象
        source_book_obj = models.Books(title=f'第{i}本书')
        # 将对象追加到列表中
        book_list.append(source_book_obj)
    models.Books.objects.bulk_create(book_list)  # 批量插入
    book_queryset = models.Books.objects.all()
    return render(request,'many_data.html',locals())

分页器推导流程

"""
django本身也自带了一个分页器 只是不好用 所以我们自己写!!!
"""

# 总体思路
  1.all()结果集支持正数的索引切片
  2.分页相关参数数学关系
  3.后端渲染前端分页代码
  4.后端限制分页展示数量
  5.当页面小于6或者大于
    
# 手写分页器

def many_data(request):
    # 批量插入数据
    book_list = []  
    for i in range(100000):
        source_book_obj = models.Books(title=f'第{i}本书')
        book_list.append(source_book_obj)
    models.Books.objects.bulk_create(book_list)  
    data_queryset = models.Books.objects.all()
    
    # 获取用户想要查看的页码
    current_page_num = request.GET.get('page')  # 后面都是基于当前页做的判断
    try:
        current_page_num = int(current_page_num)
    except Exception:
        current_page_num = 1
    # 每页展示几条数据
    per_page_num = 10
    # 起始位置
    start_num = (current_page_num - 1) * per_page_num
    # 终止位置
    stop_num = current_page_num * per_page_num
    # 前端渲染的页码数量 应该跟总数据相关 不是写死的
    # 渲染的页码数量不能太多  应该限制死 之后动态变化 展示几个即可
    show_num = 11
    all_count = data_queryset.count()
    # 判断总页数
    page_num, more = divmod(all_count, per_page_num)  # 整除,取余
    if more:
        page_num += 1
    # 获取展示给前端的页码范围,并将网址格式化输出到前端
    html = ''
    xxx = current_page_num
    if current_page_num < 6:  # 当前页码不能小于6,防止首页为负数
        xxx = 6
    for i in range(xxx-5,xxx+6):
        if current_page_num == i:
            html += '<li class="active"><a href="?page=%s">%s</a></li>'%(i,i)
        else:
            html += '<li><a href="?page=%s">%s</a></li>'%(i,i)  # html相当于后端写前端代码,拿到前端展示
    book_queryset = data_queryset[start_num:stop_num]  # 前端展示的数据对象
    return render(request,'many_data.html',locals())

# 基于当前页的数学公式分析
"""
per_page_num = 10
current_page_num            start_num               stop_num
    1                           0                       10
    2                           10                      20
    3                           20                      30
per_page_num = 5
current_page_num            start_num               stop_num
    1                           0                       5
    2                           5                       10
    3                           10                      15

start_num = (current_page_num - 1) * per_page_num
end_num = current_page_num * per_page_num
"""

封装好的自定义分页器

from utils import mypage
book_queryset = models.Books.objects.all()
# 产生分页器对象
page_obj = mypage.Pagination(current_page=request.GET.get('page'),all_count=book_queryset.count())  # 左边参数是当前页数,右边参数是总页数
# 产生分页数据对象
page_queryset = book_queryset[page_obj.start:page_obj.end]
return render(request,'many_data.html',locals())

# 前端代码
{% for book_obj in page_queryset %}
<p>{{ book_obj.title }}</p>
{% endfor %}
{{ page_obj.page_html|safe }}

参考博客:https://www.cnblogs.com/Dominic-Ji/articles/12035722.html

Forms组件

# 前戏
编写一个校验用户名和密码是否合法的功能
	前端需要自己编写获取用户数据的各种标签
  前端需要自己想方设法的展示错误的提示信息
  后端需要自己想方设法的编写校验代码(很多if判断)
  
# form组件
上面的三件事有一个人可以一次性帮你搞定>>>:form组件
  1.数据校验
  2.标签渲染
  3.展示信息

# 编写校验性组件forms类
from django import forms
class MyForm(forms.Form):
    # 用户名至少三个字符最多八个字符
    username = forms.CharField(min_length=3,max_length=8,label='用户名',
                               error_messages={
                                   'min_length':'用户名最短3位',
                                   'max_length':'用户名最长8位',
                                   'required':'用户名必填'
                               }
                               )
    # 年龄最小不能小于0 最大不能超过150
    age = forms.IntegerField(min_value=0,max_value=150,label='年龄')
    # 邮箱必须符合邮箱格式(@关键符号)
    email = forms.EmailField(label='邮箱')  # required=False 该字段可以不传值

校验数据

from app01 import views
# 1.将数据传入实例化对象
form_obj =MyForm({'username':'jason','age':18,'email':'123qq'})
# 2.查看数据是否合法(全部合法结果才是True)
form_obj.is_valid()
# 3.查看不符合条件的数据及原因
form_obj.errors
	# {'email': ['Enter a valid email address.']}
# 4.查看符合条件的数据
form_obj.cleaned_data
	# {'username': 'jason', '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 }}  # 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>
        {% for form in form_obj %}
            <p>
            {{ form.label }}
            {{ form }}
            <span style="color: red">{{ form.errors.0 }}</span>
            </p>
        {% endfor %}
        <input type="submit">
	</form>

提示信息可以自定义
	username = forms.CharField(min_length=3,max_length=8,label='用户名',
               error_messages={
                         'min_length':'用户名最短3位',
                          'max_length':'用户名最长8位',
                          'required':'用户名必填'
                               })
posted @ 2022-06-05 23:47  槐序八  阅读(65)  评论(0)    收藏  举报