首页 > 代码库 > 框架Django番外篇
框架Django番外篇
###下载和创建Django的Project
a.1在cmd中,输入下载指令
pip3 install django
2.在cmd下创建的命令
# 创建Django程序 django-admin startproject mysite # 进入程序目录 cd mysite # 启动socket服务端,等待用户发送请求 python manage.py runserver 127.0.0.1:8080 python manage.py runserver #默认 8000
b.1在Pycharm 创建以及配置(#额外配置:CSRF)
1- 模板路径 template目录 TEMPLATES = [ { ‘BACKEND‘: ‘django.template.backends.django.DjangoTemplates‘, ‘DIRS‘: [os.path.join(BASE_DIR, ‘template‘)], #!!! ‘APP_DIRS‘: True, ‘OPTIONS‘: { ‘context_processors‘: [ ‘django.template.context_processors.debug‘, ‘django.template.context_processors.request‘, ‘django.contrib.auth.context_processors.auth‘, ‘django.contrib.messages.context_processors.messages‘, ], }, }, ] - 静态文件路径 static目录 STATIC_URL = ‘/static/‘ STATICFILES_DIRS = ( #! ! ! os.path.join(BASE_DIR,‘static‘), ) 2-额外配置 ---------- (使用 中间件时,不再 配置) MIDDLEWARE = [ ‘django.middleware.security.SecurityMiddleware‘, ‘django.contrib.sessions.middleware.SessionMiddleware‘, ‘django.middleware.common.CommonMiddleware‘, #‘django.middleware.csrf.CsrfViewMiddleware‘, !!!!!! ‘django.contrib.auth.middleware.AuthenticationMiddleware‘, ‘django.contrib.messages.middleware.MessageMiddleware‘, ‘django.middleware.clickjacking.XFrameOptionsMiddleware‘, ]
a. 基本应用 form表单中添加 {% csrf_token %} b. 全站禁用 # ‘django.middleware.csrf.CsrfViewMiddleware‘, c. 局部禁用 ‘django.middleware.csrf.CsrfViewMiddleware‘, from django.views.decorators.csrf import csrf_exempt @csrf_exempt def csrf1(request): if request.method == ‘GET‘: return render(request,‘csrf1.html‘) else: return HttpResponse(‘ok‘) d. 局部使用 # ‘django.middleware.csrf.CsrfViewMiddleware‘, from django.views.decorators.csrf import csrf_exempt,csrf_protect @csrf_protect def csrf1(request): if request.method == ‘GET‘: return render(request,‘csrf1.html‘) else: return HttpResponse(‘ok‘) c. 特殊CBV from django.views import View from django.utils.decorators import method_decorator @method_decorator(csrf_protect,name=‘dispatch‘) class Foo(View): def get(self,request): pass def post(self,request): pass PS:CBV中添加装饰器 def wrapper(func): def inner(*args,**kwargs): return func(*args,**kwargs) return inner # 1. 指定方法上添加装饰器 # class Foo(View): # # @method_decorator(wrapper) # def get(self,request): # pass # # def post(self,request): # pass # 2. 在类上添加 # @method_decorator(wrapper,name=‘dispatch‘) # class Foo(View): # # def get(self,request): # pass # # def post(self,request): # pass Ajax提交数据时候,携带CSRF: a. 放置在data中携带 <form method="POST" action="/csrf1.html"> {% csrf_token %} <input id="user" type="text" name="user" /> <input type="submit" value=http://www.mamicode.com/"提交"/> <a onclick="submitForm();">Ajax提交</a> </form> <script src=http://www.mamicode.com/"/static/jquery-1.12.4.js"></script> <script> function submitForm(){ var csrf = $(‘input[name="csrfmiddlewaretoken"]‘).val(); var user = $(‘#user‘).val(); $.ajax({ url: ‘/csrf1.html‘, type: ‘POST‘, data: { "user":user,‘csrfmiddlewaretoken‘: csrf}, success:function(arg){ console.log(arg); } }) } </script> b. 放在请求头中 <form method="POST" action="/csrf1.html"> {% csrf_token %} <input id="user" type="text" name="user" /> <input type="submit" value=http://www.mamicode.com/"提交"/> <a onclick="submitForm();">Ajax提交</a> </form> <script src=http://www.mamicode.com/"/static/jquery-1.12.4.js"></script> <script src=http://www.mamicode.com/"/static/jquery.cookie.js"></script> <script> function submitForm(){ var token = $.cookie(‘csrftoken‘); var user = $(‘#user‘).val(); $.ajax({ url: ‘/csrf1.html‘, type: ‘POST‘, headers:{‘X-CSRFToken‘: token}, data: { "user":user}, success:function(arg){ console.log(arg); } }) } </script>
I.请求
如:
IP+端口号+name http://127.0.0.1:8000/login http://127.0.0.1:8000/login.html -----(.html 是伪静态)
II.Django
2.中间件
django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件。
代码:
MIDDLEWARE = [ ‘django.middleware.security.SecurityMiddleware‘, ‘django.contrib.sessions.middleware.SessionMiddleware‘, ‘django.middleware.common.CommonMiddleware‘, ‘django.middleware.csrf.CsrfViewMiddleware‘, ‘django.contrib.auth.middleware.AuthenticationMiddleware‘, ‘django.contrib.messages.middleware.MessageMiddleware‘, ‘django.middleware.clickjacking.XFrameOptionsMiddleware‘, ]
2.1
#可用于:1.黑名单 2.免登陆
2.2.自定义中间件
代码:
1.注册中间件(settings.py)
MIDDLEWARE = [ ‘django.middleware.security.SecurityMiddleware‘, ‘django.contrib.sessions.middleware.SessionMiddleware‘, ‘django.middleware.common.CommonMiddleware‘, ‘django.middleware.csrf.CsrfViewMiddleware‘, ‘django.contrib.auth.middleware.AuthenticationMiddleware‘, ‘django.contrib.messages.middleware.MessageMiddleware‘, ‘django.middleware.clickjacking.XFrameOptionsMiddleware‘, ‘m1.Middle1‘, ‘m1.Middle2‘, ]
2.创建中间件(m1.py:)
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse #中间件 一 class Middle1(MiddlewareMixin): def process_request(self, request): print(‘m1.process_request‘) # return HttpResponse(‘不要在往下周了‘) def process_response(self, request, response): print(‘m1.process_response‘) return response #中间件 二 class Middle2(MiddlewareMixin): def process_request(self, request): print(‘m2.process_request‘) # return HttpResponse(‘不要在往下周了‘) def process_response(self, request, response): print(‘m2.process_response‘) return response
执行结果:
3.路由关系的匹配
3.1.路由
3.1.1单一路由
rom django.conf.urls import url from django.contrib import admin from app01.views import love from app01.views import account urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^login.html$‘,account.login), url(r‘^logout.html$‘,account.logout), url(r‘^index.html$‘,love.index), url(r‘^others.html$‘,love.others), ]
3.1.2 基于正则的路由
url(r‘^index/(\d*)‘, views.index), url(r‘^manage/(?P<name>\w*)/(?P<id>\d*)‘, views.manage),
3.1.3 添加额外的参数
url(r‘^manage/(?P<name>\w*)‘, views.manage,{‘id‘:333}),
3.1.4为路由映射设置名称
url(r‘^home‘, views.home, name=‘h1‘), url(r‘^index/(\d*)‘, views.index, name=‘h2‘),
3.1.5路由分发
urls.py url(r‘^app01/‘, include(‘app01.urls‘)), app01.urls.py url(r‘^index.html$‘, views.index),
3.2 url(r‘^admin/‘, admin.site.urls)的 admin
django amdin是django提供的一个后台管理页面,改管理页面提供完善的html和css,使得你在通过Model创建完数据库表之后,就可以对数据进行增删改查
3.2.1创建一个用户
3.2.2向admin中增加一栏 UserInfo
3.2.3效果
4.函数(模版和数据渲染)
4.1模版
4.1.1模版的执行
模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。
4.1.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 }}
4.2自定义simple_filter ,simple_tag (模板自定义函数)
a、在app中创建templatetags模块
b、创建任意 .py 文件,如:xx.py
from django import template register = template.Library() #register 一词固定写法 @register.filter def my_upper(value): return value.upper() @register.filter def my_u(value,arg): return value+arg @register.filter def my_bool(value): return False @register.simple_tag def my_lower(value,a1,a2,a3): return value + a1 + a2 + a3
c、在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名
{% load xx %} {# 导入此句 #} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>打印字典所有的key</h1> {{ name|my_upper }} {{ name|my_u:‘666‘ }} <h2>filter</h2> {{ name|my_u:"666" }} {% if name|my_bool %} <h3>真</h3> {% else %} <h3>假</h3> {% endif %} <h2>tag</h2> {% my_lower "ALEX" "x" "SB" "V" %} </body> </html>
d、在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‘, )
4.3母版
4.3.1layout.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href=http://www.mamicode.com/"/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" /> <link rel="stylesheet" href=http://www.mamicode.com/"/static/plugins/font-awesome-4.7.0/css/font-awesome.css" /> <link rel="stylesheet" href=http://www.mamicode.com/"/static/css/commons.css" /> {% block css %}{% endblock %} </head> <body> <div class="pg-header"> <div class="logo left">老男孩后台管理</div> <div class="avatar right" style="position: relative"> <img style="width: 40px;height: 40px;" src=http://www.mamicode.com/"/static/images/1.jpg"> <div class="user-info"> <a>个人资料</a> <a>注销</a> </div> </div> <div class="rmenus right"> <a><i class="fa fa-commenting-o" aria-hidden="true"></i> 消息</a> <a><i class="fa fa-envelope-o" aria-hidden="true"></i> 邮件</a> </div> </div> <div class="pg-body"> <div class="menus"> <a> <i class="fa fa-futbol-o" aria-hidden="true"></i> 班级管理</a> <a>学生管</a> <a>老师管理</a> </div> <div class="content"> <ol class="breadcrumb"> <li><a href=http://www.mamicode.com/"#">首页</a></li> <li><a href=http://www.mamicode.com/"#">班级管理</a></li> <li class="active">添加班级</li> </ol> {% block xx %}{% endblock %} </div> </div> {% block js %}{% endblock %} </body> </html>
4.3.2index,html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for row in posts.object_list %} <li>{{ row.name }}</li> {% endfor %} </ul> <div> {% if posts.has_previous %} <a href=http://www.mamicode.com/"/index.html?page={{ posts.previous_page_number }}">上一页</a> {% endif %} {% if posts.has_next %} <a href=http://www.mamicode.com/"/index.html?page={{ posts.next_page_number }}">下一页</a> {% endif %} </div> </body> </html>
#笔记内容
layout.html {% block x1 %}{%endblock%} <h1>ff</h1> {% block x2 %}{%endblock%} <h1>2</h1>... {% block x3 %}{%endblock%} index.html {%extends ‘layout‘%} {% block x1 %}dfssssssdfsd{%endblock%} {% block x2 %}dfsdfsd{%endblock%} {% block x3 %}fff{%endblock%}
4.4include
a.pub.html(只有一个 div)
<div> <h3>特别漂亮的组件</h3> <div> <div class="title">标题:</div> <div class="content">内容:</div> </div> </div>
b.在另一个.html中,引入使用
% load xx %} {# 导入此句 #} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% include ‘pub.html‘ %} {% include ‘pub.html‘ %} {% include ‘pub.html‘ %} {% include ‘pub.html‘ %} {# <h1>打印字典所有的key</h1>#} {##} {# {{ name|my_upper }}#} {# {{ name|my_u:‘666‘ }}#} {##} {##} {##} {# <h2>filter</h2>#} {# {{ name|my_u:"666" }}#} {##} {# {% if name|my_bool %}#} {# <h3>真</h3>#} {# {% else %}#} {# <h3>假</h3>#} {# {% endif %}#} {# <h2>tag</h2>#} {# {% my_lower "ALEX" "x" "SB" "V" %}#} </body> </html>
#笔记内容
1. 模板 - 基本使用 - 母版 - 页面继承 - include - 导入小组件 pub.html <div> <h3>特别漂亮的组件</h3> <div class="title">标题:{{ name }}</div> <div class="content">内容:{{ name }}</div> </div> test.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> {% include ‘pub.html‘ %} {% include ‘pub.html‘ %} {% include ‘pub.html‘ %} </body> </html> - 函数-> 自动执行 - 模板自定义函数: - simple_filter - 最多两个参数,方式: {{第一个参数|函数名称:"第二个参数"}} - 可以做条件判断 - simple_tag - 无限制: {% 函数名 参数 参数%}
4.5Cookie
保存在客户端浏览器的键值对
4.5.1获取Cookie
request.COOKIES[‘key‘] request.get_signed_cookie(key, default=RAISE_ERROR, salt=‘‘, max_age=None) 参数: default: 默认值 salt: 加密盐 max_age: 后台控制过期时间
4.5.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=http://www.mamicode.com/‘/static/js/jquery.cookie.js‘></script> $.cookie("list_pager_num", 30,{ path: ‘/‘ });
4.6.Session
保存在服务端的数据(本质是键值对)
应用:依赖cookie
作用:保持会话(Web网站)
好处:敏感信息不会直接给客户端
Session五种类型:
- 数据库(默认)
- 缓存
- 文件
- 缓存+数据库
- 加密cookie
4.6.1 数据库Session
Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。 a. 配置 settings.py SESSION_ENGINE = ‘django.contrib.sessions.backends.db‘ # 引擎(默认) SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认) SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认) SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认) SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认) SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认) SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认) SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认) b. 使用 def index(request): # 获取、设置、删除Session中数据 request.session[‘k1‘] request.session.get(‘k1‘,None) request.session[‘k1‘] = 123 request.session.setdefault(‘k1‘,123) # 存在则不设置 del request.session[‘k1‘] # 所有 键、值、键值对 request.session.keys() request.session.values() request.session.items() request.session.iterkeys() request.session.itervalues() request.session.iteritems() # 用户session的随机字符串 request.session.session_key # 将所有Session失效日期小于当前日期的数据删除 request.session.clear_expired() # 检查 用户session的随机字符串 在数据库中是否 request.session.exists("session_key") # 删除当前用户的所有Session数据 request.session.delete("session_key") request.session.set_expiry(value) * 如果value是个整数,session会在些秒数后失效。 * 如果value是个datatime或timedelta,session就会在这个时间后失效。 * 如果value是0,用户关闭浏览器session就会失效。 * 如果value是None,session会依赖全局session失效策略。
4.6.2 缓存Session
a. 配置 settings.py SESSION_ENGINE = ‘django.contrib.sessions.backends.cache‘ # 引擎 SESSION_CACHE_ALIAS = ‘default‘ # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名 SESSION_COOKIE_SECURE = False # 是否Https传输cookie SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期 SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存 b. 使用 同上
4.6.3文件Session
a. 配置 settings.py SESSION_ENGINE = ‘django.contrib.sessions.backends.file‘ # 引擎 SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名 SESSION_COOKIE_SECURE = False # 是否Https传输cookie SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期 SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存 b. 使用 同上
4.6.4缓存+数据库Session
数据库用于做持久化,缓存用于提高效率 a. 配置 settings.py SESSION_ENGINE = ‘django.contrib.sessions.backends.cached_db‘ # 引擎 b. 使用 同上
4.6.5加密cookie Session
a. 配置 settings.py SESSION_ENGINE = ‘django.contrib.sessions.backends.signed_cookies‘ # 引擎 b. 使用 同上
扩展:Session用户验证
def login(func): def wrap(request, *args, **kwargs): # 如果未登陆,跳转到指定页面 if request.path == ‘/test/‘: return redirect(‘http://www.baidu.com‘) return func(request, *args, **kwargs) return wrap
框架Django番外篇