Django(五)母版继承、Cookie、视图装饰器等
大纲
一、内容回顾
补充:默认值
补充:命名空间
二、模板语言
1、母版继承
2、include
3、自定义simple_tag
三、Cookie
Cookie 使用总结
四、视图
1、获取用户请求相关信息以及请求头
2、CBV和FBV用户认证装饰器
二、模板语言
1、母版继承
母板:{% block title %}{% endblock %}
子板:{% extends "base.html" %} # 指定继承母版文件
{% block title %}{% endblock %}
示例:
urls.py
url(r'^model/', views.model),
views.py
def model(request):
user_list = [1, 2, 3, 43]
return render(request, 'lgeng.html', {'u': user_list})
lgeng.html
{% extends 'master.html' %} {# 导入模板文件 #} {% block title %}用户管理{% endblock %} {# 标题 #} {% block center %} {# 内容 #}
<h1>用户管理</h1>
<ul>
{% for i in u %}
<li>{{ i }}</li>
{% endfor %}
</ul>
{% endblock %} {% block css %} {# 自定义css #}
<style>
body{
background-color: white;
}
</style>
{% endblock %} {% block js %} {# 自定义js #}
<script></script>
{% endblock %}
master.html
<!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: seashell;
color: green;
}
</style>
{% block css %}{% endblock %} {# 自定义css使用 #}
</head>
<body>
<div class="pg-header">主机管理</div>
{% block center %}{% endblock %}
<script src="/static/jquery.js"></script>
{% block js %}{% endblock %} {# 自定义js使用 #}
</body>
</html>
2、include
一个html只能继承一个母版,而对于一些小组件、经常使用的,可以通过导入实现。一个html中可以有多个include
lgeng.html 内增加
{% block center %} # 内容
<h1>用户管理</h1> {% for i in u %} {# 可以循环导入 #}
{% include 'tag.html' %} {# include 导入 #}
{% endfor %} {% endblock %}
tag.html
{{ u }} {# 导入文件中也可以使用模板语言 #}
<form>
<input type="text" />
<input type="submit" />
</form>
django 是把所有母版、include 合并成一个总的字符串后,在进行渲染。
3、自定义simple_tag
比如在模板语言里,传入值5,让返回25,或传入一个列表只显示前三个,等对值的二次处理。
在模板语言中,提供了部分内置功能。有些功能不够用时就需要自定义python函数实现。
- 内置功能 —> simple_tag
{{ time_obj|date:"Y-m-d H:i:s"}} # 对传入转为日期时间格式
{{ str_obj|truncatewords:"" }} # 截取前三十个字符
{{ my_list|first|upper }} # 把第一个字符大写
{{ name|lower }} # 把传入值小写
- 自定义simple_tag
分两种方式,总结如下
# 两种方式相同配置
a. app下创建templatetags目录 (templatetags模块 --- python package )
b. 目录下任意xxoo.py文件,创建template对象 register
from django import template
register = template.Library() # 第一种方式:simple_tag
c. 定义:装饰函数
@register.simple_tag
def func(a1,a2,a3....)
return "asdfasd"
d. 配置:settings中注册APP
e. 引用:哪里用哪里顶部 {% load xxoo %}
f. 使用:{% 函数名 arg1 arg2 %}
# 缺点: 不能作为if条件
# 优点: 参数任意 # 第二种方式:filter
c.定义:装饰函数
@register.filter
def func(a1,a2)
return "asdfasd"
d. 配置:settings中注册APP
e. 引用:部 {% load xxoo %} # 引用母版extend时,load在extend下面。
f. 使用:{ 参数1|函数名:"参数二" }} # 传多个,把参数二自定义“a,b,c”多个,自己处理
# 缺点: 最多两个参数,不能加空格
# 优点: 能作为if条件
使用:
app01/templatetags/xxoo.py
from django import template register = template.Library() @register.simple_tag # 第一种方式
def houyafan(a1,a2):
return a1 + a2 @register.filter # 第二种方式
def jingze(a1,a2):
return a1 + a2
settings.py
INSTALLED_APPS = [
'……………………',
'app01',
]
templates/tpl4.html
{% load xxoo %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{% houyafan 2 7 %}</h1> <h1>{{ "maliya"|jingze:"Laoshi" }}</h1>
</body>
</html>
urls.py url(r'^tpl', views.tpl),
views.py
def tpl(request):
return render(request,"tpl4.html")
三、Cookie
把浏览器的cookie禁用掉,所有涉及到登录的网站都不能登录使用了。
Cookie :客户端浏览器上的一个文件,类似于键值对字典存储。换浏览器就不行了。
基于这个功能可以实现用户的登录认证,但cookie不是专门用来做用户验证登录的,只不过是利用这个特性实现用户登录。
urls.py
url(r'^login/', views.login),
url(r'^index/', views.index),
views.py
from django.shortcuts import render, HttpResponse,redirect
user_info = {
"lgeng":{"pwd":""},
"lgeng":{"pwd":""},
}
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) ## 设置cookie
return res
else:
return render(request,'login.html') def index(request):
# 获取当前已登录的用户
v = request.COOKIES.get("username111")
if not v:
return redirect('/login/')
return render(request,'index.html',{'current_user': v})
login.html
<body>
<form action="/login/" method="POST">
<input type="text" name="username" placeholder="用户名" />
<input type="password" name="pwd" placeholder="密码" />
<input type="submit" />
</form>
</body>
index.html
<body>
<h1>欢迎登录:{{ current_user }}</h1>
</body>
Cookie 使用总结
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的页面访问,如"/index",只能index下能访问
domain=None, Cookie生效的域名,在哪个子url下生效
secure=False, https传输(https时,设为ture)
httponly=True 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
def cookie(request):
# 获取 Cookie
# request.COOKIES # 客户端发来的所有Cookie
# request.COOKIES['username111'] # 这个Cookie,就是字典
request.COOKIES.get('username111') # 设置 Cookie
res = render(request,'index.html')
res = redirect('/index/') res.set_cookie('key',"value") # 设置cookie,关闭浏览器失效
res.set_cookie('key',"value",max_age=10) # 设置cookie, N秒后失效 # expires:设置cookie, 截止时间后失效
import datetime
current_date = datetime.datetime.utcnow()
current_date = current_date + datetime.timedelta(seconds=5)
res.set_cookie('key',"value",expires=current_date)
# cookie 加密盐
obj = HttpResponse('s')
obj.set_signed_cookie('username',"kangbazi",salt="asdfasdf") # 加密盐
request.get_signed_cookie('username',salt="asdfasdf") # 加密盐获取
四、视图
1、获取用户请求相关信息以及请求头
客户端发来的数据不只是get、post、文件等信息,还有基本的请求头,cookie、session等
想查看客户端发来的数据request提供了哪些方法?
先找到对象的类:
print(tyep(request))
导入类,查看类的内容
from django.core.handlers.wsgi import WSGIRequest
request.environ 封装了所有用户请求信息,原生数据
from django.core.handlers.wsgi import WSGIRequest for k,v in request.environ.items():
print(k,v)
print(request.environ['HTTP_USER_AGENT']) # 客户端终端信息
2、CBV和FBV用户认证装饰器
urls.py
url(r'^login/', views.login),
url(r'^index/', views.index),
url(r'^order/', views.Order.as_view()),
views.py
###################### 装饰器函数 ###########################
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
###################### FBV 认证装饰 #########################
@auth
def index(reqeust):
# 获取当前已经登录的用户
v = reqeust.COOKIES.get('username111')
return render(reqeust,'index.html',{'current_user': v})
###################### FBV 认证装饰 #########################
from django import views
from django.utils.decorators import method_decorator # 需要导入模块 #****** 第三种:给类加、指定dispatch,同第二种,不需要多写个函数 ******
@method_decorator(auth,name='dispatch')
class Order(views.View): # @method_decorator(auth) #===== 第二种:dispatch加,方法均有 =====
# 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})
# @method_decorator(auth) #--------- 第一种:每个函数都加 ---------
def post(self,reqeust):
v = reqeust.COOKIES.get('username111')
return render(reqeust,'index.html',{'current_user': v})
一、之前内容回顾
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()
//data:$('form').serilize() //-->:user=abc&pwd=aa&add=abc&email=aba&birth=aba&group_id=3
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> redirect...Ajax里不可以 用户 <<<<< 字符串 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第三个参数作为默认参数传递到view函数里
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='m2')
app01.urls app_name = 'app01' <-- 添加 app_name
urlpatterns=[
url(r'/index/', views.index, name = 'n1'),
url(r'/home/' , views.home, name = 'n2)'
]
reverser('m1:n1') --> /admin/index/
reverser('m1:n2') --> /admin/home/
reverser('m2:n1') --> /crm/index/
reverser('m2:n2') --> /crm/home/
3、获取请求
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、数据库操作
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='') 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')
补充:默认值
看上面内容
补充:命名空间
a. project.urls.py
两个url同指向一个
from django.conf.urls import url,include urlpatterns = [ # namespace 命名空间
url(r'^a/', include('app01.urls', namespace='m1')),
url(r'^b/', include('app01.urls', namespace='m2')),
]
b. app01.urls.py
from django.conf.urls import url
from app01 import views app_name = 'app01'
urlpatterns = [
url(r'^(?P<pk>\d+)/$', views.detail, name='detail')
]
c. app01.views.py
def detail(request):
return HttpResponse('pk')
以上定义带命名空间的url之后,使用name反向生成URL(反解)的时候,应该如下:
v = reverse('m1:detail')
python代码里{% url 'm1:detail' %}
模板语言里
django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而使路由系统变得简洁。
转载请务必保留此出处:http://www.cnblogs.com/lgeng/articles/7365723.html
<!-- END -->
《版权说明》: 本文转自 -- http://blog.csdn.net/fgf0/article/details/418066
Django(五)母版继承、Cookie、视图装饰器等的更多相关文章
- python 之 Django框架(Django框架简介、视图装饰器、request对象、Response对象)
12.33 Django框架简介: MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器( ...
- Django视图函数函数之视图装饰器
FBV模式装饰器: 普通函数的装饰器(语法糖@) views.py from django.shortcuts import render def wrapper(f): def inner(*arg ...
- Django---MTV和MVC的了解,Django的模版语言变量和逻辑,常见的模板语言过滤器,自定义过滤器,CSRF了解,Django的母版(继承extends,块block,组件include,静态文件的加载load static),自定义simple_tag和inclusion_tag
Django---MTV和MVC的了解,Django的模版语言变量和逻辑,常见的模板语言过滤器,自定义过滤器,CSRF了解,Django的母版(继承extends,块block,组件include,静 ...
- 浅谈Django的中间件与Python的装饰器
浅谈Django的中间件 与Python的装饰器 一.原理 1.装饰器是Python的一种语法应用,利用闭包的原理去更改一个函数的功能,即让一个函数执行之前先到另外一个函数中执行其他需求语句,在执行该 ...
- django之基于cookie和装饰器实现用户认证
示例1 # Create your views here. user = "a" pwd = "a" def login(request): if reques ...
- simple_tag,filte,分页以及cookie和装饰器
自定义simple_tag 内置的方法 首先Django中包含了很多内置的方法: 这里通过lower实现 在views视图函数中写如下代码: def tp3(request): name= " ...
- [Python自学] Flask框架 (1) (Flask介绍、配置、Session、路由、请求和响应、Jinjia2模板语言、视图装饰器)
oldboy:s9day114 参考博客:https://www.cnblogs.com/wupeiqi/articles/7552008.html 一.Flask简介 1.安装Flask pip i ...
- django的FBV和CBV的装饰器例子
备忘 def auth(func): def inner(request,*args,**kwargs): u = request.COOKIES.get('username111') if not ...
- 使用IntelljIDEA生成接口的类继承图及装饰器模式
类图生成方法 以一个装饰器模式实现数学运算的例子为例. 安装 Intellj Ultimate , lience server: http://xdouble.cn:8888/ 在类上右键点击 cla ...
随机推荐
- Jenkins高级用法 - Pipeline 安装
一.总体介绍 总体介绍内容摘自 玩转Jenkins Pipeline(大宝鱼) 1.核心概念 Pipeline,简而言之,就是一套运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的 ...
- 从零开始学习PYTHON3讲义(十一)计算器升级啦
(内容需要,本讲中再次使用了大量在线公式,如果因为转帖网站不支持公式无法显示的情况,欢迎访问原始博客.) <从零开始PYTHON3>第十一讲 第二讲的时候,我们通过Python的交互模式来 ...
- Cache【硬盘缓存工具类(包含内存缓存LruCache和磁盘缓存DiskLruCache)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 内存缓存LruCache和磁盘缓存DiskLruCache的封装类,主要用于图片缓存. 效果图 代码分析 内存缓存LruCache和 ...
- Vue2.0源码阅读笔记(一):选项合并
Vue本质是上来说是一个函数,在其通过new关键字构造调用时,会完成一系列初始化过程.通过Vue框架进行开发,基本上是通过向Vue函数中传入不同的参数选项来完成的.参数选项往往需要加以合并,主要有 ...
- Mac使用Gradle上传jar到中央仓库(最完整的采坑记录)
前言 当我们封装完成我们自己做的工具之后,那我们肯定想要发给别人让别人来进行使用,上传到中央仓库是一种引入时最方便的选择. 网上有很多教程,但是大多都是maven和windows的环境. 今天就来记录 ...
- k8s应用机密信息与配置管理(九)--技术流ken
secret 应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥.将这些信息直接保存在容器镜像中显然不妥,Kubernetes 提供的解决方案是 Secret. Secret 会以 ...
- 分享基于 websocket 网页端聊天室
博客地址:https://ainyi.com/67 有一个月没有写博客了,也是因为年前需求多.回家过春节的原因,现在返回北京的第二天,想想,应该也要分享技术专题的博客了!! 主题 基于 websock ...
- unity transform 常用操作
1.寻找物体 1.1 寻找满足条件的子物体 ` public static Transform FindObj(Transform transform, Func<Transform, bool ...
- C#实现多级子目录Zip压缩解压实例
参考 https://blog.csdn.net/lki_suidongdong/article/details/20942977 重点: 实现多级子目录的压缩,类似winrar,可以选择 ...
- python的学习笔记01_2变量 常量 注释 用户交互 格式化输出
变量是什么? 变量的作用 Variables are used to store information to be referenced and manipulated in a computer ...