Django(4)html模板继承、模板导入、分页实现

时间:2022-02-20 03:53:37

1.获取所有请求信息

导入模块:from django.core.handlers.wsgi import WSGIRequest

request.environ:包含所有的请求信息,可以打印看一下,它是一个字典

2.html模板之继承(一个网页只能继承一个模板)

公用模板master.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %} {% endblock %}</title>#这里设置title可替换,就用block块
    <link rel="stylesheet" href="/static/commons.css" />
    <style>
        .pg-header{
            height: 50px;
            background-color: seashell;
            color: green;
        }
    </style>
    {% block css %} {% endblock %} #这里设置css替换块
</head>
<body>
    <div class="pg-header">小男孩管理</div>
     {% block content %} {% endblock %}#这里设置内容替换块
    <div>
        <a>asdf</a>
        <a id="">asdf</a>
        <a>asdf</a>
        <a>asdf</a>
        <a>asdf</a>
    </div>
    <iframe src="/"></iframe>
</body>
</html>

自定义网页tp1.html

{% extends 'master.html' %}#继承模板,指明继承的模板名
{% block title %}用户管理{% endblock %} #在相应的块里插入内容,块的顺序可以不跟模板中块的顺序相同
{% block content %}  #在相应的块里插入内容
    <h1>用户管理</h1>
    <ul>
        {% for i in u %}
            <li>{{ i }}</li>
        {% endfor %}
    </ul>
    {% for i in u %}  #导入模板
        {% include 'tag.html' %}
    {% endfor %}
{% endblock %}
{% block css %}  #在相应的块里插入内容
    <style>
        body{
            background-color: red;
        }
    </style>
{% endblock %}
{% block js %}
    <script></script>
{% endblock %}

3. html网页之模板导入

自定义模板文件tag.html,它是html的一个或多个标签,并不是完整的网页

<div>
    <input type='text' />
</div>

在网页中导入模板

{% extends 'master.html' %}#模板继承
{% block title %}用户管理{% endblock %}
{% block content %}
    <h1>用户管理</h1>
    <ul>
        {% for i in u %}
            <li>{{ i }}</li>
        {% endfor %}
    </ul>
    {% for i in u %}
        {% include 'tag.html' %}#模板导入,这里就相当于将tag.html里的内容写在了这里
    {% endfor %}
{% endblock %}
{% block css %}
    <style>
        body{
            background-color: red;
        }
    </style>
{% endblock %}
{% block js %}
    <script></script>
{% endblock %}

4.模板之自定义simple_tag,

步骤:

simple_tag
                a. app下创建templatetags目录
                b. 任意xxoo.py文件
                c. 创建template对象 对象名必须叫register
                d. xxoo.py的内容
                                    from django import template
                                    from django.utils.safestring import mark_safe
                                    register = template.Library()
                                   @register.simple_tag
                                   def houyafan(a1,a2,a3):
                                           return a1 + a2     #最终在页面上呈现的值
                e. settings中注册APP
                f. 在要使用simple_tag的html顶部 写上{% load xxoo %}
                g.在网页中使用该函数 
{% 函数名 arg1 arg2 %} 缺点: 不能作为if条件 优点: 参数任意

5.模板之自定义filter

filter
                a. app下创建templatetags目录
                b. 任意xxoo.py文件
                c. 创建template对象 register
                d.xxoo.py中的内容
                 from django import template
from django.utils.safestring import mark_safe
register = template.Library()
@register.filter
def jiajingze(a1,a2):
print(a2,type(a2))
return a1 + str(a2)
                e. settings中注册APP
f. 顶部 {% load xxoo %}
g. {{ 参数1|函数名:"参数二,参数三" }}或传数字参数 {{ 参数1|函数名:数字 }}
缺点: 最多两个参数,不能加空格
优点: 能作为if条件

6.实现分页,并且自定义选择显示的行数

一、自定义一个分页类,命名为pagination.py,在项目下新建一个目录utils,将pagination.py放在该目录下,这样其他app也可以调用这个类

__author__ = 'Administrator'
from django.utils.safestring import mark_safe

class Page:
    def __init__(self, current_page, data_count, per_page_count=10, pager_num=7):
        self.current_page = current_page  #当前页码
        self.data_count = data_count    #数据总量
        self.per_page_count = per_page_count #每页显示数据的行数
        self.pager_num = pager_num  # 每页显示页码的个数

    @property  #加上这个属性后,在调用start函数时就不用加括号了
    def start(self): #每页显示的开始页码数
        return (self.current_page - 1) * self.per_page_count

    @property
    def end(self):  #每页显示的结束页码数
        return self.current_page * self.per_page_count

    @property
    def total_count(self):  #获取总页数
        v, y = divmod(self.data_count, self.per_page_count)
        if y:  #如果y不为0,则总页数v加一
            v += 1
        return v   #

    def page_str(self, base_url):  #给前端传递html链接,base_url:自定义跳转的url
        page_list = []  #初始化一个列表,它存放html链接,也就是可以点击的那些按钮

        if self.total_count < self.pager_num:#如果总页数小于每页应该显示的页码数,则只显示的页码数等于总页数
            start_index = 1
            end_index = self.total_count + 1
        else:
            if self.current_page <= (self.pager_num + 1) / 2:#显示第一页的页码数,当点击第一个页码的时候不会出现异常
                start_index = 1
                end_index = self.pager_num + 1
            else:
                start_index = self.current_page - (self.pager_num - 1) / 2
                end_index = self.current_page + (self.pager_num + 1) / 2
                if (self.current_page + (self.pager_num - 1) / 2) > self.total_count:#显示最后一页的页码数,
                                                                                    # 当点击最后一个页码的时候不会出现异常
                    start_index = self.total_count - self.pager_num + 1
                    end_index = self.total_count + 1

        if self.current_page == 1:#显示上一页
            prev = '<a class="page" href="javascript:void(0);">上一页</a>'
        else:
            prev = '<a class="page" href="%s?p=%s">上一页</a>' % (base_url, self.current_page - 1,)
        page_list.append(prev)

        for i in range(int(start_index), int(end_index)):#列出每一页的  “上一页 46 47 48 49 50 51 52 53 54 下一页  GO”
            if i == self.current_page:#给当前页码加上颜色属性
                temp = '<a class="page active" href="%s?p=%s">%s</a>' % (base_url, i, i)
            else:
                temp = '<a class="page" href="%s?p=%s">%s</a>' % (base_url, i, i)
            page_list.append(temp)

        if self.current_page == self.total_count:
            nex = '<a class="page" href="javascript:void(0);">下一页</a>'
        else:
            nex = '<a class="page" href="%s?p=%s">下一页</a>' % (base_url, self.current_page + 1,)
        page_list.append(nex)
        #增加跳转框,输入指定数字即可跳转,如果不输入数字则不会跳转
        jump = """
            <input type='text' class='inp' /><button onclick='jumpto(this,"%s?p=");'>GO</button>
            <script>
                function jumpto(ths,base){
                    var val = ths.previousSibling.value;
                    if(val){
                        location.href = base + val;
                    }else{
                        "%s#"
                    }
                }
            </script>
        """ % (base_url,base_url)

        page_list.append(jump)

        page_str = mark_safe("".join(page_list))#mark_safe可以将传递给前端的标签字符串转变为标签

        return page_str

二、在views.py中调用类pagination.py即可

from  utils import pagination
LIST = []
for i in range(500):
    LIST.append(i)

def user_list(request):
    current_page = request.GET.get('p', 1)
    current_page = int(current_page)

    per_page_count = request.COOKIES.get('per_page_count',10)#获取cookie值,
    per_page_count = int(per_page_count)
    page_obj = pagination.Page(current_page,len(LIST),per_page_count)

    data = LIST[page_obj.start:page_obj.end]

    page_str = page_obj.page_str("/user_list/")

    return render(request, 'user_list.html', {'li': data,'page_str': page_str})

三、前端user_list.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .pagination .page{
            display: inline-block;
            padding: 5px;
            background-color: cyan;
            margin: 5px;
        }
        .pagination .page.active{
            background-color: brown;
            color: white;
        }
    </style>
</head>
<body>
    <ul>
        {% for item in li %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>

    <div>
        <select id="ps" onchange="changePageSize(this)"><!--jquery绑定js,必须加this参数-->
            <option value="10">10</option>
            <option value="30">30</option>
            <option value="50">50</option>
            <option value="100">100</option>
        </select>
    </div>

    <div class="pagination">
        {{ page_str }}
    </div>
    <script src="/static/jquery-1.12.4.js"></script>
{#    导入jquery.cookie.js插件,它必须放在jQuery下边#}
    <script src="/static/jquery.cookie.js"></script>
    <script>
        $(function(){//自执行函数,选择页数,并且在页面改变页数
                var v = $.cookie('per_page_count', {'path': "/user_list/"});//设置cookie,仅限/user_list/路径的cookie生效
                $('#ps').val(v);
        });
        function changePageSize(ths){
            var v = $(ths).val();//获取选择的值
            $.cookie('per_page_count',v, {'path': "/user_list/"});//设置cookie
            location.reload();//自动刷新页面
        }
    </script>
</body>
</html>

7.利用cookie实现用户登录

1、获取Cookie:

1
2
3
4
5
6
request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='加密盐', max_age=None)
    参数:
        default: 默认值
           salt: 加密盐,get与set的值必须相同
        max_age: 后台控制过期时间

2、设置Cookie:

1
2
3
4
5
6
7
8
9
10
11
12
13
rep = HttpResponse(...) 或 rep = render(request, ...)
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐',...)
    参数:
        key,              键
        value='',         值
        max_age=None,     超时时间,在一定秒数后失效
        expires=None,     超时日期,在指定时分秒后失效
        path='/',         Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
        domain=None,      Cookie生效的域名
        secure=False,     https传输
        httponly=False    只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

由于cookie保存在客户端的电脑上,所以,JavaScript和jquery也可以操作cookie。

1
2
<script src='/static/js/jquery.cookie.js'></script>
$.cookie("list_pager_num"30,{ path: '/' });

 

基于cookie实现用户登录,不管访问什么页面,都会自动跳转到登录页面

views.py

user_info = {
    "},
    'kanbazi': {'pwd': "kkkkkkk"},
}
def login(request):
    if request.method == "GET":
        return render(request,'login.html')
    if request.method == "POST":
        u = request.POST.get('username')
        p = request.POST.get('pwd')
        dic = user_info.get(u)
        if not dic:
            return render(request,'login.html')
        if dic['pwd'] == p:
            res = redirect('/index/')
            # res.set_cookie('username111',u,max_age=10)# 10秒后cookie失效
            # import datetime
            # current_date = datetime.datetime.utcnow()#获取当前时间
            # invalud_date = current_date + datetime.timedelta(seconds=5) #在当前时间基础上加5秒
            # res.set_cookie('username111',u,expires=current_date)  #指定的时分秒后cookie失效
            res.set_cookie('username111',u) #给res设置cookie
            return res
        else:
            return render(request,'login.html')

def auth(func):
    def inner(reqeust,*args,**kwargs):
        v = reqeust.COOKIES.get('username111')
        if not v:
            return redirect('/login/')
        return func(reqeust, *args,**kwargs)
    return inner

@auth
def index(reqeust):
    # 获取当前已经登录的用户
    v = reqeust.COOKIES.get('username111')
    return render(reqeust,'index.html',{'current_user': v})

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form action="/login/" method="POST">
        <input type="text" name="username" placeholder="用户名" />
        <input type="password" name="pwd" placeholder="密码" />
        <input type="submit" />
    </form>
</body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>欢迎登录:{{ current_user }}</h1>
</body>
</html>