1 Template
mysql设置时间(pycharm使用的非本地时间)
set global time_zone=’+8:00’;
show variables like ‘%time_zone%’;
if
- if 语句需要以endif结尾
- {% if forloop.counter|divisibleby:2 %}
- 对2整除
- {% ifequal a b %}
- 如果a、b值相等
for
- for 语句需要以endfor结尾
- {% empty %}下方的语句是在数据为空时的渲染
- forloop
- forloop.count 计数
- forloop.count0 从零计数
- forloop.revcounter 倒数
- forloop.first 是否是第一个
- forloop.last 是否是最后一个
template标签
- 有成对标签和单标签
过滤器
- {{var|过滤器}}
- 加法过滤器
- {{ p.page|add:5 }}
- 没有减法过滤器,可以通过加负数代替
- lower 转小写
- {{ p.pname|lower }}
- upper 转大写
- join {{ students|join ‘=’ }}
- default {{ var|default value }}
- 日期转字符串 {{ dateVal|date:‘y-m-d’ }}
结构标签
-
block
- 块;
- {% block 模板 %} {% endblock %};
- 首次出现代表规划;
- 第二次出现代表填充以前的规划;
- 第三次出现则会覆盖之前的内容;
- 使用 {{ block.super }} 继承之前的内容,避免覆盖;
- 即增量式操作;
-
extends
- 继承一个模板;
- 获取父模板中的所有结构;
-
见 base.html、home_mine.html 和 home.html;
-
include
- 将页面作为一个组件放入其他页面;
- 见 footer.html 和 home_mine.html;
-
尽量少用include;
-
如果页面继承自一个父模板,子模版直接写html结构无法生效;
- 只能在既有block中进行编写;
静态资源
- 动静分离
- 创建静态文件夹
- css文件在static文件中创建后,需要在settings中进行设置
- STATICFILES_DIRS = [ os.path.join(BASE_DIR, ‘static’) ]
- 否则无法生效;
- css文件使用方式:
- {% load static %} // 头部引入静态资源
- <link rel=“stylesheet” href="{% static ‘css/test.css’ %}">
- 坑点
- 仅能在debug模式中使用
- 以后需要自己单独处理
2 Views
urls
-
位置参数
- 在get请求中,一个圆括号代表一个参数
- url(r’getTime/(\d+)/(\d+)/(\d+)/’, views.get_time, name=‘get_time’),
- href={% url ‘second:get_time’ value1 value2 value3 %}
- 在函数中直接获取:def student(request, s_id):
-
关键字参数
- url(r’getDate/(?P\d+)/(?P\d+)/(?P\d+)/’, views.get_date),
- def get_date(request, year, day, month):
- href={% url ‘second:get_time’ key1=value1 key2=value2 key3=value3 %}
- 获取顺序可以改变,是按照名称进行匹配的,和顺序无关;
url反向解析
- url的位置极有可能发生变化,这样能够避免因url变化带来的问题;
- 1 在项目的urls中进行注册
- url(r’Two/’, include((‘Two.urls’, ‘Two’), namespace=‘second’)),
- 2 在应用(子路由)的urls中进行配置
- url(r’learn/’, views.learn, name=‘learn’)
- 3 模板中的使用
- 两者通过namespace加name找到对应路由;
- <a href={% url ‘second:learn’ %}>Go learn</a>
- 取代 href="/Two/learn/" 这样的硬编码;
- 即使url发生变化,依然可以获取页面/完成请求;
GET
- http://localhost:8000/Two/haveRequest/?hobby=1&hobby=2
- 用以上方式发起GET请求,需用以下方式获取数据:
hobby = request.GET.get('hobby')
hobbies = request.GET.getlist('hobby')
- 上一个只获取最后一个(‘2’),下一个获取整个数组({‘hobby’: [‘1’, ‘2’]});
错误页面自定义
- 直接复写对应页面即可
- 比如对于404报错,直接在templates里面编写404页面即可;
- 关闭Debug
- 关闭调试状态
- 实现原则
- 就近原则
双R
- Request
- 内置属性
- method
- path
- GET
- 类字典结构
- 一个key对应多个值
- get获取最后一个值
- getlist获取所有
- POST
- META
- 访问者的所有信息
- REMOTE=>ADDR:IP信息
- 内置属性
- Response
- 服务器返回给客户端的数据
- 不使用模板,直接返回HttpResponse();
- 调用模板,进行渲染;
- render(request, template_name[, context])
- request 请求体对象
- template_name 模板路径
- context 字典参数,用来填坑
- HttpResponseRedirect
- 响应重定向,实现服务器内部跳转,暂时重定向
- return HttpResponseRedirect(’/grade/2017’)
- 推荐使用反向解析
url = reverse('app:hello') if random.randrange(10) > 5: return HttpResponseRedirect(url)
- 302是暂时重定向
- JsonResponse
- 返回Json数据的请求,通常用于ajax;
- HttpResponsePermanentRedirect
- 重定向,永久性
- 301是永久重定向
- HttpResponseNotAllowed
- 405
- 服务器返回给客户端的数据
JSON
- JsonObject
- {}
- key-value
- JsonArray
- []
- JsonObject可以和JsonArray嵌套;
- 给移动端/ajax都是json;
3 会话技术
- 出现场景
- 服务器如何识别客户端
- http是短链接
- 请求生命周期
- 从Request开始
- 到Response结束
- 终类
- Cookies
-
客户端会话技术
-
数据存储在客户端
-
键值对存储
-
支持过期时间
-
默认cookies自动携带,本网站所有Cookies
-
Cookies不能跨域名,跨网站
-
通过Http请求
-
response.set_cookie(key, value, max_age=None, expires=None)
- max_age:整数,用于指定过期时间
- 秒
- max_age=0,浏览器关闭即失效
- max_age=None,永不失效
- expires:整数、datetime、timedelta,用于指定过期时间
- expires=timedelta(10),10天不过期
- 以上两个选一个即可
- max_age:整数,用于指定过期时间
-
不支持中文
-
加密(加盐)
- response.set_signed_cookie(key, value, salt)
- 解密
- request.get_signed_cookie(key, salt=salt)
-
删除cookie
- response.delete_cookie(key)
-
实例在DjangoView => App
-
- Session
- 服务端会话技术
- 数据存储在服务器中
- 存储在django_session表中;
- Django默认将Session持久化到数据库中
- 实例在DjangoView => Two
- Session默认过期时间是14天
- 主键是字符串,数据使用了数据安全
- Session依赖于cookie
- 清空cookie后,session也失效了;
- 实际上也就实现了登陆退出;
# 设置cookie response.set_cookie("token", token) # 获取会话的值 request.session.get('username') # 仅删除cookie,数据库中未删除 response.delete_cookie('sessionid') # cookie和数据库中的session同时删除 # 常用 request.session.flush()
- Token
- 服务端会话技术,实质还是身份识别
- 自定义的Session
- Session依赖于cookie
- cookie依赖于浏览器
- 部分浏览器不支持,手机也不支持
- 如在Web页面中开发,则和Session基本一致
- 如在移动端或者客户端中,常以 json 的格式传递,需要移动端存储Token,需要获取Token关联数据的时候,主动传递Token
- 用于不支持cookie的场景
- Cookies
CSRF
- 防跨站攻击
- 防止恶意注册,确保是我们自己的客户端
- 使用cookie中的csrftoken进行验证、传输
- 服务器发送给客户端,客户端获取cookie,并进行编码转换
- 实现原理
- 在存在 csrf_token 标签的页面中,响应会自动设置一个cookie,csrftoken
- 提交时会自动验证csrftoken
- 验证通过,正常执行以后流程,验证不通过,直接403
<form action="{% url 'two:login' %}" method="post"> {% csrf_token %} <span>用户名:</span><input type="text" placeholder="请输入用户名" name="username"> <br> <button>登陆</button> </form>
登陆
- 登陆后设置cookies
- 后台设置cookie,而不是前端
- 后台发现不带用户名(或为空)则重定向至登陆页面;
算法
- 编码解码
- Base64
- urlencode
- 摘要算法、指纹算法、杂凑算法
- MD5,SHA
- MD5 默认128位二进制
- 32位的十六进制
- 32位的Unicode
- 单向不可逆
- 不管输出多长,输出都是固定长度
- 只要输入有任意的变更,输出都会发生巨大变化
- MD5,SHA
- 加密
- 对称加密
- 一把钥匙
- DES、AES
- 加密解密效率高
- 钥匙一旦丢失,所有数据丢失
- 非对称加密
- 两把钥匙
- 公钥(1024位)和私钥(2048位),互相制约
- RSA、PGP
- 安全性最高
- 算法复杂,事件长
- 对称加密
其它
locals
- 内置函数
- 将局部变量用字典的方式进行打包
- key是变量名,value就是数值
优秀程序
- 松耦合
- 高内聚
新 GET url 形式的尝试
- url:localhost:8000/login/?username=test1&id=12
- urls 中的 url 配置:
- url(r’^get-test/’, views.get_test, name=‘get-test’),
def get_test(request): if request.method == "GET": result = {} username = request.GET.get('username') id = request.GET.get('id') result['username'] = username result['id'] = id return JsonResponse(result)