Django——母版,自定义simple-tag函数,分页,cookie
templates
1、母版
extends方法
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>{% block title %} {% endblock %}</title> 6 <link rel="stylesheet" href="/static/commons.css" /> 7 <style> 8 .pg-header{ 9 height: 50px; 10 background-color: seashell; 11 color: green; 12 } 13 </style> 14 {% block css %} {% endblock %} 15 </head> 16 <body> 17 <div class="pg-header">小男孩管理</div> 18 <div> 19 <a>asdf</a> 20 <a id="">asdf</a> 21 <a>asdf</a> 22 <a>asdf</a> 23 <a>asdf</a> 24 </div> 25 <iframe src="/"></iframe> 26 </body> 27 </html>
include方法
引入母版文件
1 {% extends 'master.html' %} 2 {% block title %}用户管理{% endblock %} 3 {% block content %} 4 <h1>用户管理</h1> 5 <ul> 6 {% for i in u %} 7 <li>{{ i }}</li> 8 {% endfor %} 9 </ul> 10 {% for i in u %} 11 {% include 'tag.html' %} 12 {% endfor %} 13 {% endblock %} 14 15 {% block css %} 16 <style> 17 body{ 18 background-color: red; 19 } 20 </style> 21 {% endblock %} 22 23 {% block js %} 24 <script> 25 //写js文件 26 </script> 27 {% endblock %}
小tips
HTML中引入CSS <link rel = 'stylesheet' herf = 'stactic/css文件/' />
2、自定义simple-tag
官方的
{{ item.event_start|date:"Y-m-d H:i:s"}} // 输入字符串转换成后面的时间格式 {{ bio|truncatewords:"30" }} // 只取输入的30个字符 {{ my_list|first|upper }} // 听说是第一个字符大写 {{ name|lower }} // 把字符串变成小写
自定制函数步骤
1、在app目录下创建templatetags目录
2、创建任意(abc).py文件
3、创建template对象register #一定要这么写不能改名字
from django import template register = template.Library()
4、书写函数加入装饰器
a. @register.simple_tag def add(v1,v2,v3): return v1 + v2 + v3 b. @register.filter def subtraction(a1,a2): return a1 - a2
5、在settings文件中注册app
6、在html文件顶部引入该py文件
{% load abc %} //引入py文件 只能用{% %} 调用函数的方法 a. {% add 1 2 3 %} //调用函数加传参数 b. {{ 5|subtraction:2 }} //函数名后面不能加空格 小tips {% load abc %} //先引入load {% extends " xx.html " %}
两种方法的优缺点
simple_tag 缺点: 不能作为if条件 优点: 参数任意 filter 缺点: 最多两个参数,不能加空格 优点: 能作为if条件 {% if {{ 5|subtraction:2 }} %}
3.分页
我们可以通过从后端发送标签(<a herf="...">123</a>)到前端的方法实现页面的某些功能
但django默认会认为所有在页面显示的都是不安全的(为了防止XSS攻击),so有以下操作
//假设传来的参数是page_list 方法一(前端) {{ page_list|safe }} //加上|safe 就变成安全的 方法二(后端) from django.utils.safestring import mark_safe def page_list(id,arg): #内容瞎写的,别信 result = "<input type='text' id='%s' class='%s' />" %(id,arg,) return render(....,{'page_list',mark_safe(result)}) #make_safe(里面的东西就变成安全的)fenye
我们可以(在根目录建立一个文件夹utils)写一个类,里面封装着分页的操作(里面有一个bug,跳转框输入数字 不管存不存在都会跳转到那个页面)
1 from django.utils.safestring import mark_safe 2 3 4 class Page: 5 def __init__(self, current_page, data_count, per_page_count=10, pager_num=7): 6 self.current_page = current_page 7 self.data_count = data_count 8 self.per_page_count = per_page_count 9 self.pager_num = pager_num 10 11 @property #可以直接调用不用加(),好看一些 12 def start(self): 13 return (self.current_page - 1) * self.per_page_count 14 15 @property 16 def end(self): 17 return self.current_page * self.per_page_count 18 19 @property 20 def total_count(self): 21 v, y = divmod(self.data_count, self.per_page_count) 22 if y: 23 v += 1 24 return v 25 26 def page_str(self, base_url): 27 page_list = [] 28 29 if self.total_count < self.pager_num: 30 start_index = 1 31 end_index = self.total_count + 1 32 else: 33 if self.current_page <= (self.pager_num + 1) / 2: 34 start_index = 1 35 end_index = self.pager_num + 1 36 else: 37 start_index = self.current_page - (self.pager_num - 1) / 2 38 end_index = self.current_page + (self.pager_num + 1) / 2 39 if (self.current_page + (self.pager_num - 1) / 2) > self.total_count: 40 end_index = self.total_count + 1 41 start_index = self.total_count - self.pager_num + 1 42 43 if self.current_page == 1: 44 prev = '<a class="page" href="javascript:void(0);">上一页</a>' 45 else: 46 prev = '<a class="page" href="%s?p=%s">上一页</a>' % (base_url, self.current_page - 1,) 47 page_list.append(prev) 48 49 for i in range(int(start_index), int(end_index)): 50 if i == self.current_page: 51 temp = '<a class="page active" href="%s?p=%s">%s</a>' % (base_url, i, i) 52 else: 53 temp = '<a class="page" href="%s?p=%s">%s</a>' % (base_url, i, i) 54 page_list.append(temp) 55 56 if self.current_page == self.total_count: 57 nex = '<a class="page" href="javascript:void(0);">下一页</a>' 58 else: 59 nex = '<a class="page" href="%s?p=%s">下一页</a>' % (base_url, self.current_page + 1,) 60 page_list.append(nex) 61 62 jump = """ 63 <input type='text' /><a onclick='jumpTo(this, "%s?p=");'>GO</a> 64 <script> 65 function jumpTo(ths,base){ 66 var val = ths.previousSibling.value; 67 location.href = base + val; 68 } 69 </script> 70 """ % (base_url,) 71 72 page_list.append(jump) 73 74 page_str = mark_safe("".join(page_list)) 75 76 return page_str
直接调用类里面的方法
from utils import pagination LIST = [] for i in range(500): LIST.append(i) def user_list(request): current_page = request.GET.get('p', 1) #1是干嘛的 ==> 第一次请求的时候默认看第一页 current_page = int(current_page) page_obj = pagination.Page(current_page,len(LIST)) data = LIST[page_obj.start:page_obj.end] page_str = page_obj.page_str("/user_list/") return render(request, 'user_list.html', {'data': data,'page_str': page_str})
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <ul> 9 {% for i in data %} 10 <li>{{ i }}</li> 11 {% endfor %} 12 </ul> 13 14 <div> 15 {{ page_str }} 16 </div> 17 </body> 18 </html>
小Tips
a. for i in range(1,5): print(i) >>1,2,3,4 b. herf = "javascript:void(0)" <==> herf = '#' //啥也不干
c. /index/?p=1 获取方法: page = request.GET.get('p')
4.cookie
获取cookie
request.COOKIES['key'] request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None) 参数: default: 默认值 salt: 加密盐 max_age: 后台控制过期时间
设置cookie
rep = HttpResponse(...) 或 rep = render(request, ...) 或 redirect('/index/') rep.set_cookie(key,value,...) rep.set_signed_cookie(key,value,salt='加密盐',...) 参数: key, 键 value='', 值 max_age=None, 超时时间 #max_age=10 以s作单位 expires=None, 超时时间(IE requires expires, so set it if hasn't been already.) path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问 domain=None, Cookie生效的域名 secure=False, https传输 httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
import datetime current_date = datetime.datetime.utcnow() current_date = current_date+datetime.timedelta(seconds=5) #5s
小tips
import hashlib m = hashlib.md5('sdcxzmvdvk') #这里面加的就是盐 m.update('abc123')
前端也可以设置,获取cookie
<script src='/static/jquery'></script> <script src='/static/js/jquery.cookie.js'></script> //设置 $.cookie("key", 'value',{ path: '/' ,...}); //获取 $.cookie('key')
示例:
views.py
1 def cookie(request): 2 # 3 # request.COOKIES 4 # request.COOKIES['username111'] 5 request.COOKIES.get('username111') 6 7 response = render(request,'index.html') 8 response = redirect('/index/') 9 # 设置cookie,关闭浏览器时失效 10 response.set_cookie('key',"value") 11 # 设置cookie, N秒后失效 12 response.set_cookie('username111',"value",max_age=10) 13 # 设置cookie, 截止时间失效 14 import datetime 15 current_date = datetime.datetime.utcnow() 16 current_date = current_date + datetime.timedelta(seconds=5) 17 response.set_cookie('username111',"value",expires=current_date) 18 response.set_cookie('username111',"value",max_age=10) 19 20 # request.COOKIES.get('...') 21 # response.set_cookie(...) 22 obj = HttpResponse('s') 23 24 obj.set_signed_cookie('username',"kangbazi",salt="asdfasdf") 25 request.get_signed_cookie('username',salt="asdfasdf") 26 27 return response
login.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <form action="/login/" method="POST"> 9 <input type="text" name="username" placeholder="用户名" /> 10 <input type="password" name="pwd" placeholder="密码" /> 11 <input type="submit" /> 12 </form> 13 </body> 14 </html>
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>欢迎登录:{{ current_user }}</h1> </body> </html>