Python之路Day21-自定义分页和cookie
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python之路Day21-自定义分页和cookie相关的知识,希望对你有一定的参考价值。
本节知识点概要
1.URL
2.views
- 请求其他信息
- 装饰器
3.Templates
- 母版
- 自定义
4.Models操作
5.分页(自定义分页)
6.cookie
7.session
8.Form验证
- 缓存
- 中间件
- 信号
- CSRF
- Admin/ModelForm
上节内容回顾
1.请求周期
url> 路由 > 函数或类 > 返回字符串或者模板语言?
form表单提交
提交 -> url路由系统 > 函数或类中的方法 - 执行其他操作,最终返回 HttpResponse(‘....‘) render(request,‘index.html‘) redirect(‘/index/‘) 返回字符串 > > 返回给用户 (当接受到redirect时)自动发起另外一个请求 --> url .....
Ajax请求
$.ajax({ url: ‘/index/‘, data: {‘k‘: ‘v‘, ‘list‘: [1,2,3,4], ‘k3‘: JSON.stringfy({‘k1‘: ‘v‘}))}, $(form对象).serilize() type: ‘POST‘, dataType: ‘JSON‘: traditional: true, success:function(d){ location.reload() # 刷新 location.href = "某个地址" # 跳转 } }) 提交 -> url -> 函数或类中的方法 HttpResponse(‘{}‘) render(request, ‘index.html‘, {‘name‘: ‘v1‘}) <h1>{{ name }}</h1> --> <h1>v1</h1> XXXXXXX redirect... 用户 <<<<< 字符串
2.路由系统URL
a. /index/ -> 函数或类 b. /index/(\\d+) -> 函数或类 c. /index/(?P<nid>\\d+) -> 函数或类 d. /index/(?P<nid>\\d+) name=‘root‘ -> 函数或类 reverse() {% url ‘root‘ 1%} e. /crm/ include(‘app01.urls‘) -> 路由分发 f. 默认值 url(r‘^index/‘, views.index, {‘name‘: ‘root‘}), def index(request,name): print(name) return HttpResponse(‘OK‘) g. 命名空间 /admin/ include(‘app01.urls‘,namespace=‘m1‘) /crm/ include(‘app01.urls‘,namespace=‘m1‘)
app01.urls /index/ name = ‘n1‘
reverser(‘m1:n1‘)
3.viwes
def func(request): request.POST request.GET request.FILES request.getlist request.method request.path_info return render,HttpResponse,redirect
4.模板引擎
render(request, ‘index.html‘) # for # if # 索引. keys values items all
5.medels
单表
class User(models.Model): username = models.CharField(max_length=32) email = models.EmailField() 有验证功能 Django Admin 无验证功能: User.objects.create(username=‘root‘,email=‘asdfasdfasdfasdf‘) User.objects.filter(id=1).update(email=‘666‘)
多表:
创建数据库结构 class UserType(models.Model): name = models.CharField(max_length=32) class User(models.Model): username = models.CharField(max_length=32) email = models.EmailField() user_type = models.ForeignKey("UserType")
跨表操作: user_list = User.objects.all() for obj user_list: obj.username,obj.email,obj.user_type_id,obj.user_type.name,obj.user_type.id //获取单个列表 user = User.objects.get(id=1) user.
//获取指定列内容 User.objects.all().values("username","user_type__name",) 多对多 class UserType(models.Model): name = models.CharField(max_length=32) class User(models.Model): username = models.CharField(max_length=32) email = models.EmailField() user_type = models.ForeignKey("UserType") m = models.ManyToMany(‘UserGroup‘) class UserGroup(models.Model): name = .... 操作: obj = User.objects.get(id=1) obj.m.add(2) obj.m.add(2,3) obj.m.add(*[1,2,3]) obj.m.remove(...) obj.m.clear() obj.m.set([1,2,3,4,5]) # 多个组,UserGroup对象 obj.m.all() obj.m.filter(name=‘CTO‘)
一、views 请求的其他信息
from django.core.handlers.wsgi import WSGIRequest print(type(request)) print(request.environ) for k,v in request.environ.items(): print(k,v) print(request.environ[‘HTTP_USER_AGENT‘])
装饰器
FBV
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
CBV
from django import views from django.utils.decorators import method_decorator @method_decorator(auth,name=‘dispatch‘) class Order(views.View): # @method_decorator(auth) # def dispatch(self, request, *args, **kwargs): # return super(Order,self).dispatch(request, *args, **kwargs) # @method_decorator(auth) def get(self,reqeust): v = reqeust.COOKIES.get(‘username111‘) return render(reqeust,‘index.html‘,{‘current_user‘: v}) def post(self,reqeust): v = reqeust.COOKIES.get(‘username111‘) return render(reqeust,‘index.html‘,{‘current_user‘: v})
二、templates
模板继承
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %} {% endblock %}</title> <link rel="stylesheet" href="/static/commons.css"> <style> .pg-header{ height: 48px; background-color: #1F78A4; color: white; font-size: 22px; line-height: 48px; } </style> {% block css %} {% endblock %} </head> <body> <div class="pg-header">管理系统</div> {% block content %} {% endblock %} <script src="/static/jquery.js"></script> {% block js %} {% endblock %} </body> </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: transparent; } </style> {% endblock %} {% block js %} <script> </script> {% endblock %}
1、模版的执行
模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。
def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
from django import template t = template.Template(‘My name is {{ name }}.‘) c = template.Context({‘name‘: ‘Adrian‘}) print t.render(c)
import datetime from django import template import DjangoDemo.settings now = datetime.datetime.now() fp = open(settings.BASE_DIR+‘/templates/Home/Index.html‘) t = template.Template(fp.read()) fp.close() html = t.render(template.Context({‘current_date‘: now})) return HttpResponse(html
from django.template.loader import get_template from django.template import Context from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() t = get_template(‘current_datetime.html‘) html = t.render(Context({‘current_date‘: now})) return HttpResponse(html)
return render_to_response(‘Account/Login.html‘,data,context_instance=RequestContext(request))
2、模版语言
模板中也有自己的语言,该语言可以实现数据展示
- {{ item }}
- {% for item in item_list %} <a>{{ item }}</a> {% endfor %}
forloop.counter
forloop.first
forloop.last - {% if ordered_warranty %} {% else %} {% endif %}
- 母板:{% block title %}{% endblock %}
子板:{% extends "base.html" %}
{% block title %}{% endblock %} - 帮助方法:
{{ item.event_start|date:"Y-m-d H:i:s"}}
{{ bio|truncatewords:"30" }}
{{ my_list|first|upper }}
{{ name|lower }}
3、自定义simple_tag
a、在app中创建templatetags模块
b、创建任意 .py 文件,如:xx.py
#!/usr/bin/env python #coding:utf-8 from django import template from django.utils.safestring import mark_safe register = template.Library() @register.simple_tag def my_simple_time(v1,v2,v3): return v1 + v2 + v3 @register.simple_tag def my_input(id,arg): result = "<input type=‘text‘ id=‘%s‘ class=‘%s‘ />" %(id,arg,) return mark_safe(result)
c、在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名
{
%
load xx
%
}
d、使用simple_tag
{% my_simple_time 1 2 3%} {% my_input ‘id_username‘ ‘hide‘%}
e、在settings中配置当前app,不然django无法找到自定义的simple_tag
INSTALLED_APPS = ( ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘app01‘, )
缺点:不能作为if条件
优点:参数任意
更多见文档:https://docs.djangoproject.com/en/1.10/ref/templates/language/
4、自定义filter
a. app下创建templatetags目录
b. 任意xxoo.py文件
c. 创建template对象 register
d.
@register.filter def func(a1,a2) return "asdfasd"
e. settings中注册APP
f. 顶部 {% load xxoo %}
g. {{ 参数1|函数名:"参数二,参数三" }} {{ 参数1|函数名:数字 }}
缺点:最多两个参数,不能加空格
优点:能作为if条件
三、分页
前端设置为安全
{{page_str|safe }}
后端设置为安全
from django.utils.safestring import mark_safe page_str=""" <a href="/user_list/?p=1">1</a> <a href="/user_list/?p=2">2</a> <a href="/user_list/?p=3">3</a> """ page_str=mark_safe(page_str)
范例:
__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 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: v += 1 return v def page_str(self, base_url): page_list = [] 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: end_index = self.total_count + 1 start_index = self.total_count - self.pager_num + 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)): 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‘ /><a onclick=‘jumpTo(this, "%s?p=");‘>GO</a> <script> function jumpTo(ths,base){ var val = ths.previousSibling.value; location.href = base + val; } </script> """ % (base_url,) page_list.append(jump) page_str = mark_safe("".join(page_list)) return page_str
from utils import pagination LIST=[] for i in range(509): LIST.append(i) def user_list(request): current_page = request.GET.get(‘p‘, 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‘,{‘li‘:data,‘page_str‘:page_str})
四、cookie和session
cookie
相当于浏览器上的一个文件
<!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>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>欢迎登录:{{ current_user }}</h1> </body> </html>
1、获取Cookie:
request.COOKIES[‘key‘] request.get_signed_cookie(key, default=RAISE_ERROR, salt=‘‘, max_age=None) 参数: default: 默认值 salt: 加密盐 max_age: 后台控制过期时间
2、设置Cookie:
rep = HttpResponse(...) 或 rep = render(request, ...) rep.set_cookie(key,value,...) rep.set_signed_cookie(key,value,salt=‘加密盐‘,...) 参数: key, 键 value=‘‘, 值 max_age=None, 超时时间 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获取(不是绝对,底层抓包可以获取到也可以被覆盖)
由于cookie保存在客户端的电脑上,所以,JavaScript和jquery也可以操作cookie。
<script src=‘/static/js/jquery.cookie.js‘></script> $.cookie("list_pager_num", 30,{ path: ‘/‘ }); Session
...
以上是关于Python之路Day21-自定义分页和cookie的主要内容,如果未能解决你的问题,请参考以下文章
python之路_day71_django分页及session介绍