Django第三方组件, forms与分页器

Django自带的序列化组件

"""
以后我们用的序列化组件是DRF 这里学自带的是提前看一下效果
虽然可以进行手动的来进行序列化,
但是操作并没有django自带的序列化组件那么方便
"""
from app01 import models
from django.http import JsonResponse
from django.core import serializers
def d_data(request):
    # 前后端分离之后 django orm产生的queryset无法直接被前端识别 还是需要json格式数据(硬通货)
    # data_list = []  # [{}, {}, {}]
    # user_queryset = models.User.objects.all()
    # for user_obj in user_queryset:
    #     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)
    user_queryset = models.User.objects.all()
    ret = serializers.serialize('json', user_queryset)
    return HttpResponse(ret)

批量数据操作

def many_data(request):
    # 循环插入10万条数据(频繁走数据库操作 效率极低 不推荐!!!)
    # for i in range(100000):
    #     models.Book.objects.create(title=f'第{i}本书')
    '''批量插入'''
    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())

分页器自行推导代码

后端代码:       
    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()
    """
    100 10 10
    101 10 11
    99  10 10
    """
    page_num, more = divmod(all_count, per_page_num)
    if more:
        page_num += 1
    html = ''
    min_num = current_page_num
    if current_page_num < 6:
        min_num = 6
    for i in range(min_num - 5, min_num + 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)
    book_queryset = data_queryset[start_num:stop_num]


前端代码:
<div class='text_center'>
        {% for book_obj in book_queryset %}     
           <p>{{ book_obj.title }}</p>     
        {% endfor %}   

     <nav aria-label="Page navigation">     
         <ul class="pagination">           
             <li>               
                 <a href="#" aria-label="Previous">          
                    <span aria-hidden="true">«</span>      
                </a>               
               {{ html|safe }}               
                 <a href="#" aria-label="Next">         
                    <span aria-hidden="true">»</span>        
                </a>         
             </li>        
         </ul>   
     </nav>
</div>

Django自带分页器

后端代码:
    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())


前端代码:
    <div class="text-center">
        {% for page_obj in page_queryset %}
            <p>{{ page_obj.title }}</p>
        {% endfor %}
        {{ page_obj.page_html|safe }}
    </div>

forms组件

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

# 基本使用
from django import forms
class MyForm(forms.Form):
    # 用户名至少三个字符最多八个字符
    username = forms.CharField(min_length=3,max_length=8)
    # 年龄最小不能小于0 最大不能超过150
    age = forms.IntegerField(min_value=0,max_value=150)
    # 邮箱必须符合邮箱格式(@关键符号)
    email = forms.EmailField()

校验数据

from app01 import views
# 1.将数据传入实例化对象
form_obj =MyForm({'username':'dragon','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': 'dragon', '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':'用户名必填'
                               })

posted @ 2022-05-21 00:30  Yietong  阅读(23)  评论(0)    收藏  举报