首页 > 其他分享 >Django自定义系列

Django自定义系列

时间:2022-11-27 21:46:54浏览次数:41  
标签:count 系列 自定义 self Django current pager page

Django自定义系列

目录

模板层-自定义过滤器、标签、inclusion_tag

# 共有步骤

# 在settings中的INSTALLED_APPS添加当前app的名字
INSTALLED_APPS = ['app01',]



# 在文件夹app01中创建子文件夹templatetags



# 在templatetags新建任意.py文件



# 在该文件中导入所需名称

from django import template
register = template.Library()

自定义过滤器(最多两个参数)

@register.filter(name='sum_filter')
def my_sum(a1,a2):
    return a1 + a2

自定义过滤器调用

{% load mytag %}
<p>{{ a1|sum_filter:a2 }}</p>

自定义标签(可以有多个参数)

@register.simple_tag(name='my_tag')
def index(a, b, c, d):
    return f'{a}/{b}/{c}/{d}'

自定义标签调用

{% load mytag %}
<p>{% my_tag 'a' 'b' 'c' 'd' %}</p>

自定义inclusion_tag之书写inclusion_tag主代码

@register.inclusion_tag('left_menu.html')
def left(n):
    data = [f'第{i}项' for i in range(n)]
    return locals() #将data传递给left_menu.html 即 return {'data':data}

自定义inclusion_tag之定义渲染工具页面

# 新建'left_menu.html'
# 书写代码
'''
<ul>
    {% for datum in data %}
        <li>{{ datum }}</li>
    {% endfor %}
</ul>
'''

自定义inclusion_tag调用

{% load mytag %}
{% left 9 %}

自定义模板

模板页面制作

# 新建模板文件
# 书写模板代码

'''
<div class="panel-body">

{% block var_content %}
    <div class="jumbotron">
      <h1>Hello, world!</h1>
      <p>...</p>
      <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
    </div>
{% endblock %}

</div>
'''

实例页面调用

'''
{% extends 'home.html' %}

{% block var_content %}
    <h1>注册页面</h1>
{% endblock %}
'''

# 一般情况下,模板页面应该至少有三块可以被修改的区域
'''
1.css区域
{% block css %}
{% endblock %}
2.html区域
{% block content %}
{% endblock %}
3.js区域
{% block js %}
{% endblock %}
'''

导入模板

# 即将模板页面模块化,然后实例页面直接使用语法将模板页面所有代码直接导入
{% include 'part.html' %}

自定义分页器

# 新建或进入utils文件夹
# 创建任意名称.py文件

在该文件内定义分页器类

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)







        '''
        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())
        '''

        #
        #   <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>
        #

在试图函数中导入类

from utils.mypage import Pagination

使用该类创建对象、使用对象属性截取数据列表,将数据列表返回

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())

自定义forms组件

新建python文件

# 位置根据项目需要

在该文件中定义自己的forms类

from django import forms
from app01 import models



class MyRegForm(forms.Form):
    username = forms.CharField(label='用户名',
                               min_length=3,
                               max_length=8,
                               error_messages={
                                   'required': '用户名不能为空',
                                   'min_length': '用户名最少3位',
                                   'max_length': '用户名最大8位',
                               },
                               widget=forms.widgets.TextInput(attrs={
                                   'class': 'form-control'
                               })
                               )
    password = forms.CharField(label='密码',
                               min_length=6,
                               max_length=12,
                               error_messages={
                                   'required': '密码不能为空',
                                   'min_length': '密码最少6位',
                                   'max_length': '密码最大12位',
                               },
                               widget=forms.widgets.PasswordInput(attrs={
                                   'class': 'form-control'
                               })
                               )

    confirm_password = forms.CharField(label='确认密码',
                                       min_length=6,
                                       max_length=12,
                                       error_messages={
                                           'required': '确认密码不能为空',
                                           'min_length': '确认密码最少6位',
                                           'max_length': '确认密码最大12位',
                                       },
                                       widget=forms.widgets.PasswordInput(attrs={
                                           'class': 'form-control'
                                       })
                                       )
    email = forms.EmailField(label='邮箱地址',
                             error_messages={
                                 'required': '邮箱不能为空',
                                 'invalid': '邮箱格式不正确'
                             },
                             widget=forms.widgets.EmailInput(attrs={
                                 'class': 'form-control'
                             })
                             )


    # label即在渲染时可用的标签说明,min_length、max_length即校验条件,error_messages即自定义错误提示信息,要注意对于特殊字段例如email的错误提示信息稍有不同,widget即定义标签具体属性

        # 局部钩子:校验用户名是否已存在
    def clean_username(self):
        username = self.cleaned_data.get('username')
        is_exist = models.UserInfo.objects.filter(username=username)
        if is_exist:
            self.add_error('username', '用户名已存在')
        return username

    # 全局钩子:校验两次密码是否一致
    def clean(self):
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if not password == confirm_password:
            self.add_error('confirm_password', '两次输入的密码不一致')
        return self.cleaned_data

forms组件其他参数

'''
label 标签名
error_messages 自定义错误提示
initial 默认值
required 是否必填
widget 设置input标签类型(password/select等),并且可以通过传参设置标签属性:
widget=forms.widgets.PasswordInput(attrs={'class':'formcontrol c1 c2','me':'george'})
RegexValidator
更多input标签类型的渲染:https://www.cnblogs.com/Dominic-Ji/p/9240365.html
'''
# RegexValidator校验
from django.core.validators import RegexValidator
email = forms.EmailField(label='邮箱',error_messages={'invalid':'邮箱格式不正确','required':'邮箱不能为空'})
# 仍然属于第一道校验,在钩子函数之前

forms组件使用

form_obj = MyRegForm(request.POST)
if form_obj.is_valid():
    cleaned_data = form_obj.cleaned_data
    cleaned_data.pop('confirm_password')
    file_obj = request.FILES.get('avatar')
    if file_obj:
        cleaned_data['avatar'] = file_obj

        models.UserInfo.objects.create_user(**cleaned_data)
        back_dict['url'] = '/login/'

标签:count,系列,自定义,self,Django,current,pager,page
From: https://www.cnblogs.com/missfxy/p/16930675.html

相关文章

  • Django前后端通信
    Django前后端通信目录Django前后端通信Ajax前后端传输数据的编码格式(contentType)ajax发送json格式数据ajax发送文件django自带的序列化组件ajax结合sweetalert批量插入数......
  • Django模型层
    Django模型层目录Django模型层测试脚本单表操作查看内部sql语句的方式双下划线查询外键增删改正反向多表查询聚合查询分组查询F与Q查询开启事务ORM常用字段及参数数据库查......
  • Django模板层
    Django模板层目录Django模板层模板语法传值过滤器标签自定义过滤器、标签、inclusion_tag模板的继承模板的导入模板语法传值#模板语法形式:1.{{变量相关}}2.{%逻辑......
  • Django初识
    Django初识目录Django初识基本操作项目主要文件介绍初始技巧静态文件配置Request对象form表单request.methodrequest.POSTrequest.GETpycharm连接数据库(MySQL)django连接数......
  • Django路由层
    Django路由层目录Django路由层路由匹配无名分组有名分组反向解析无名分组反向解析有名分组反向解析路由分发名称空间伪静态虚拟环境null路由匹配#url方法第一个参数是......
  • Django版本差异
    Django版本差异#一、路由层'''django1.x路由层使用url方法django2.x/3.x路由层使用path方法可以根据习惯使用re_pathpath方法支持5种转换器'''fromdjango.ur......
  • Django-ORM简介
    DjangoORM目录DjangoORM字段的增删改查数据的增删改查创建表关系null#即对象关系模型#类——表#对象——记录#对象属性(值)——记录某个字段(值)#在models.py中写......
  • Java Excel导出动态自定义单元格样式
    根据表格内容定义单元格样式效果图:文章描述两种,一种创建生成时定义样式,另一种在excel在写入文件前修改样式关键代码一/***数据动态设置样式*......
  • DP系列-最长公共子序列
    原题意:给定两个字符串s1和s2,返回这两个字符串的最长公共子序列的长度,如果不存在则返回0。子序列是不连续的顺序列,如ace是abcde的子序列,aec就不是示例1:s1="abced",s2......
  • jquery011-自定义函数-执行
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title></head><bodystyle="width:980px;margin:0auto"><h1>例子1</h1><......