Django简介
- pip安装,配置环境变量 ……python\script django-admin
创建、操作django项目:
- 创建工程项目
- 方式一:cmd命令行 django-admin startproject 项目名
- 方式二:IDE,pycharm中创建django项目
- 在使用pycharm过程中,需要设置django server:
- 名字是项目名字
- 默认ip,端口
- environment variable: DJANGO_SETTINGS_MODULE 工程项目名.settings PYTHONUNBUFFERED : 1
- python解释器
- 在使用pycharm过程中,需要设置django server:
- 运行:
- 命令行中, python manage.py runserver 指定host:端口 host和端口可省略,使用默认
- pycharm中完成配置。 在“select run /debug configuration” 中选定配置好的django ,点击运行
- django项目目录结构:
- 与项目同名的文件夹 :完成程序的整体配置
- init
- settings :配置文件
- urls :url对应关系
- wsji :wsgi规范
- manage.py :管理django程序
- python manage.py 运行
- python manage.py startapp 程序名
- python manage.py makemigrations
- python manage.py migrate
- 创建app
- 在cmd命令行中,进入工程项目目录, python manage.py startapp 指定app名
- windows python中可通过 Teminal 运行上面的命令
- 常见app :cmdb templates openstack……
- app内部结构文件功能(cmdb):
- migrations: 数据修改表结构
- 内部有django自动创建的数据库修改表结构的操作记录
- __init__ 把文件夹转成包
- admin django为我们提供的后台管理
- apps 配置当前app
- models: ORM,写入指定的类,通过命令创建和修改数据库结构
- tests: 单元测试
- views: 和cmdb相关的所有业务,业务逻辑代码
- migrations: 数据修改表结构
- 不同文件、模块间的调用过程中,注意核实settings中环境的配置
- 配置模板的路径
- 在settings中,DIRS:[os.path.join(BASE_DIR,"模板包名字")] 一般的是templates
- 配置静态文件的路径
- 在settings中,STATIC_DIR后面,加上STATICFILES_DIRS = (os.path.join(BASE_DIR,"静态文件名字"),) 一般地静态文件名为static
- django项目创建步骤
- 1 创建django工程 django-admin startproject 工程项目名
- 2 创建app cd工程文件夹 python manage.py startapp app名
- 3 静态文件配置
- 4 模板配置
- 5 csrf
- 6 定义路由规则 url.py 请求字段——》响应函数名(视图函数、)
- 7 定义视图函数 app 下 views 判断数据发送方式,通过request拿数据,数据处理,数据返回
- HttpResponse-传字符串、 HttpResposnse(" 字符串 ")
- render-传HTML模板路径、 render(request ,"abc.html",{ 替换形式字典 })
- redirect-传 /URL) redirect(' /abc/ddd ')
- django请求
- 请求 一般情况下,GET方式用来获取数据,POST用于提交数据。其他的提交方式还有PUT/DELET等
- 路由关系映射
- 视图函数
- 数据 html模板
- 渲染以后返回给用户
- 视图函数
- 后台数据获取
- request是前端数据的打包
- request.body 用户发起请求的请求体
- request.GET request.POST request.FILES ……
- request.Meta()
- request.method() request.path_info request.COOKIES ……
- 一般情况下,GET方式用来获取数据,POST用于提交数据。其他的提交方式还有PUT/DELET等
- request.POST.get()
- request.GET.get()
- request.POST.getlist()
- request.FILES.get()
- request.FILES.size()
- request.FILES.chunks()
- request.path_info 获取当前url信息
- request中封装了url请求的所有信息,实际上是以类的形式存在的
- 要查看请求体的详细信息,需要导入WSGIRequest , from django.core.handlers.wsgi import WSGIRequest
- request.environ 可以拿到请求体的完整信息,字典形式存放的
- request.environ[ ] 可以拿到指定的信息内容, 例如,request.environ['HTTP_USER_AGENT']
- reverse函数,可以根据路由的名称,反向解析出完整的路由信息。
- 导入,from django.urls import reverse
- 对于未指明namespace的, reverse(路由name); 对于指明namespace的, reverse(命名空间namespace:路由name)
- 返回内容
- return HttpResponse() 返回简单字符串 return render(request," html",{ 替换内容 })返回取到数据渲染后的html文件内容 return redirect( ' 重定向url ' )
- 数据返回的时候,cookie的设置内容是通过响应头传递回去的
- FBV(function base views) 与 CBV(class base views)
- CBV 本质上,通过dispatch反射,实现根据数据请求的发送方式选择不同方法执行
- CBV方式,可以通过重写dispatch,实现自定制功能
- 装饰器(定义方式是一样的,调用方式不一致)
- 基于FBV的
-
1 #---------基于FBV的装饰器实现COOKIE登录验证----------- 2 3 def auth(func): 4 def inner(request,*args,**kwargs): 5 v = request.COOKIES.get("user111") 6 if not v: 7 return redirect('/login/') 8 return func(request,*args,**kwargs) 9 return inner 10 11 @auth 12 def func01(request): 13 return HttpResponse("hello world")
-
- 基于CBV的
- 基于CBV的视图函数,加装饰器时,需要导入模块 from django.utils.decorators import method_decorator 然后通过@method_decorator(auth)加装饰器
- 具体调用方式:
- 方式一,可以直接怼类函数进行装饰
- 方式二:对类里的方法全都装饰的情况下,可以利用dispatch函数。重写dispath函数,并加上装饰器
- 方式三:直接在类名上面加装饰器,本质上,方式三是对方式二的简化
-
1 #---------基于CBV的装饰器实现COOKIE登录验证----------- 2 3 def auth(func): 4 def inner(request,*args,**kwargs): 5 v = request.COOKIES.get("user111") 6 if not v: 7 return redirect('/login/') 8 return func(request,*args,**kwargs) 9 return inner 10 11 @method_decorator(auth,name="dispatch") #方式三 12 class Order(views.View): 13 14 @method_decorator(auth) #方式二 15 def dispatch(self,request,*args,**kwargs): 16 return super(Order,self).dispatch(request,*args,**kwargs) 17 18 @method_decorator(auth) #方式一 19 def func1(self,request): 20 return HttpResponse("hello world普通函数")
-
- 基于FBV的
- 后台数据获取
- 路由系统(urls)
- 1 一 一对应静态匹配,url('index/',views.index) url('home/',views.Home.as_view()) 在设置路由关系时字段内容最后要加上$终止符,否则在匹配过程中,会由于不是截止的精确匹配,因而前后优先级导致匹配错乱。 例如,url('index/$',views.index)
- 2 利用正则实现动态匹配(类似传递位置参数) url('detail-(\d+).html',views.detail)
- 3 利用正则表达式的分组实现(在函数调用时,参数以关键字形式传递) url(“detail-(?p<nid>\d+)-(?p<uid>\d+).html”,views.detail) 为了方便,在定义函数的时候,直接用不定长参数*args,**kwargs定义。
- 获取当前url信息,request.path_info
- reverse的应用,利用reverse函数,可以根据路由名称,返回具体的路径。
- 路由分发,当请求到顶级(项目同名)url的时候,通过include,根据请求的关键字,对请求进行一个分发,同时在不同的app中建立局部的urls文件,避免不同app之间urls放在一起,增强系统的易读易维护性。 顶级url负责分发, 例如, url("monitor/",include("app003.urls")),url("cmdb/",include("app06.urls"))
- url默认值,在路由系统中,可以给视图函数传递默认值,此时,需要保证视图函数有对应的形参用于接收默认值。 例如 url("index/",views.index,{"name":"root"}) ,这时候,index视图函数的name参数会接收路由调用时自动传递过来的默认值root。
- url命名空间。在路由分发的情况中,如果出现不同的url指向相同函数的情况时,单纯使用url的name没有办法得到确切的url路径,这时需要同时利用url的name,和定义路由时所一并定义的额命名空间。 定义命名空间的基本语法 url(“a/”,include("app01.urls",namespace="a1")) url(“b/”,include("app01.urls",namespace="b1")) 通过reverse( ‘ 命名空间namespace:路由name ’ ) 可以确定url路径
- Models,数据库操作(ORM)
- 主流ORM可以分成 db first (需要先自己登陆数据库建立表结构再创建相应的类,操作表结构),code first(先写代码,用类创建数据库表)两类
- 创建类
- 根据类创建数据表
- 在app下,models.py中,创建类,继承models.Model。注意,models.py命名不能改,否则会报错
- 通过类创建表
- 在类中,通过models的方法,定义字段,其中可选属性null=True,定义可以为空。例如 username=models.CharField(max_length=32)
- 创建字段的方法,分为三大类,字符串、数字、时间、二进制,常用的有:CharField定义一般的字符串 IntegerField定义数字 DateField定义日期 DateTimeField定义时间 EmailField 定义邮箱格式 GenericIPAddressField定义IP类型 URLField定义URL AutoField定义自增列,必须加属性primary_key=True
- 字段的常用参数有: null——》是否为空,default——》默认值,primary_key——》主键,db_column列名,db_index——》索引,uique——》唯一索引,unique_for_date,unique_for_mounth,unique_for_year,auto_now——》创建时,自动获取时间,auto_now_add——》更新时,自动获取当前时间,choices——》元组形式定义分组,定义了admin中显示的下拉框 blank——》在admin中,定义是否为空 verbose_name——》在admin中设置是否为中文 editable——》设置admin中是否可编辑 error_messages——》错误提示 help_text——》在admin中提示信息 validators——》自定义错误信息 protocol用于GenericIPAddressField设置ip协议类型
- 通过manage创建表结构, python manage.py makemigrations 注意,在创建之前,需要把在settings中,把当前app名加入INSTALLED_APPS
- 执行migrate命令,在数据库中创建表,类似于数据库的确认操作, python manage.py migrage
- 用django默认的数据库是sqlite,如果用mysql,需要,1 在settings中,把数据库引擎设置修改,
#DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.mysql',
# 'NAME': 'dbname',
# 'USER':'root',
# 'PASSWORD':'mysql',
# 'HOST':'',
# 'PORT':'',
# }
# } - 另外,需要注意的是,利用django使用mysql时引擎默认是用的mysqldb,但是,当前python3.x中,还没有mysqldb。需要在和项目同名的文件夹下,__init__文件中,设置
#import pymysql
# pymysql.install_as_MySQLdb()
- 在app下,models.py中,创建类,继承models.Model。注意,models.py命名不能改,否则会报错
- 根据类对数据库表中的数据进行各种操作,注意:增加、更新、查询传递参数时,都可以通过 ** 传递字典进行操作
- 增加:
- 方式一,直接创建 models . 表名 .objects.create(字段1:数值,字段2……) 当字段较多,可以先建一个存储信息的字典,然后把字典穿进去,当传递字典时,需要在字典名前加 ** models . 表名 .objects.create(**字典名)
- 方式二,通过创建一个对象信息,然后把保存对象 obj=models . 表名(字段1:数值,字段2……) obj.save()
- 当定义字段时,使用models.EmailField() models.GenericIPAddressField()等特殊格式时,如果用 create创建,或者用update更新,都不会有格式验证。只有在执行django admin时会有格式验证。
- 查询:
- all拿到的是对象形式存储信息的QuerySet(形式上类似于列表) models.数据表名.objects.all()
- 对于查询的结果,可以通过 .order_by()进行排序 models.数据表名.objects.all().order_by() models.UserInfo.objects.filter(id__gt=1).order_by()
- .first() 结果中的第一个 .count()对结果进行计数 .last() 结果中的最后一个
- 利用filter添加where查询条件,结果也是以QuerySet存储 models.数据表名.objects.filter(筛选条件)
- models.UserInfo.objects.filter(id=1)
- models.UserInfo.objects.filter(id__gt=1)
- models.UserInfo.objects.filter(id__lt=1)
- models.UserInfo.objects.filter(id__gte=1)
- models.UserInfo.objects.filter(id__lte=1)
- 另外,用models.数据表名.objects.get(筛选条件) 能取到单条数据,取不到内容,报错!需要try一下
- 一般情况下,查询的结果,不论是all()或者是通过fiter()取到的都是queryset形式储存的对象的序列,再链一个values() 拿到的是queryset形式存储的字典的序列可以指定取出的字段 例如models.UserInfo.objects.filter(id__gt=1).values(‘id’,'name'), 如果链一个values_list() 拿到的则是queryset形式存储的元组的序列,可以通过索引值,拿到指定的字段
- all拿到的是对象形式存储信息的QuerySet(形式上类似于列表) models.数据表名.objects.all()
- 删除:
- models.数据表名.objects.filter(筛选条件).delete()
- 修改(更新):
- models.数据表名.objects.filter(筛选条件).update(字段=修改的数值)
- 增加:
- 外键
- 外键关系名 = models.ForeignKey(to=关联表名,to_field=关联字段,on_delete=models.CASCADE) 外键关系名_id ——》外键字段(自动) ondelete=models.CASCSDE 实在django2.x以后版本加入的,最明显的一个作用,是避免两个表之间的数据不一致。models.CASCADE是默认情况下的取值,另外的取值分别为:
- CASCADE:此值设置,是级联删除。
PROTECT:此值设置,是会报完整性错误。
SET_NULL:此值设置,会把外键设置为null,前提是允许为null。
SET_DEFAULT:此值设置,会把设置为外键的默认值。
SET():此值设置,会调用外面的值,可以是一个函数。
- CASCADE:此值设置,是级联删除。
- 调用执行过程中,外键关系名指向关联表的对象
- 当用all(),filter()等方法直接拿到结果的时候,跨表拿内容,直接用 “ queryset存储的表对象 . 外键关系名 . 字段名 ” 来获取 例如item.group_foreignkey.name。此时的外键关系可理解为封装在queryset对象中的子级对象,指向关联表。
- 当用values(),或者values_list() 拿到结果的时候,跨表拿内容,不能用 “ . ” 需要改成双下划綫“ __ ” 例如:item.group_foreignkey__name。并且,在用values,或者values_list() 须在视图函数中完成,
- 通过建立外键,可以实现表之间的一对多的关系创建
- 反向查询外键关联关系表。
- 外键关系名 = models.ForeignKey(to=关联表名,to_field=关联字段,on_delete=models.CASCADE) 外键关系名_id ——》外键字段(自动) ondelete=models.CASCSDE 实在django2.x以后版本加入的,最明显的一个作用,是避免两个表之间的数据不一致。models.CASCADE是默认情况下的取值,另外的取值分别为:
- 多对多关系建立
- 方式一,通过手动建立第三张表作为关系表,分别通过外键和另外的两张表建立外键关联,最终实现两张关联表之间的多对多
- 方式二,利用r=models.ManyToManyField() ,在创建原始的关联表的时候,由django自动创建多对多的第三张关系表。r作为操作句柄可以实现对第三张关系表的操作。
- 利用r操作对应关系的时候,先获取一张关联表(创建r的表)中的对象, 例如, obj=models.关联表名.get(id=1)
- 然后通过r对关联关系进行操作。 obj.r.add(2) obj.r.add(1,2,3) obj.r.add(*[3,4,5,6]) obj.r.remove(2,3) obj.r.clear() obj.r.set([1,2,3]) 用set设定更新关系时,传列表不用加* 。 obj.r.all() 拿到的是一个另一张表的对象, obj.r.filter()
- 方式二默认的只可以创建两张表之间的关系。如果需要多张表之间建立关系,需要用方式一。
- 验证功能
- 根据类创建数据表
- Templates 模板
- 可以直接定义html,然后在视图函数中进行调用
- 在布局重复的情况下,可以使用html母版,通过继承母版的设置,提高程序的可读性、易维护性,降低维护成本
- 1 定义布局母版html ,在母版中用{%block 模块名字%}{%endblock%}定义可以替换的模块及其位置。
- 2 在引用html文件中,声明引用的母版 {%extends “布局母版html文件名字”% }
- 3 定义好当前html文件用于替换布局母版的内容。 {%block 模块名字%}自定义的内容{%endblock%}
- 4 在具体页面中还有特有的css,js的情况,在母版中留出自定制css,js的位置,在具体页面中用自定义替换即可
- 对于页面中的重复布局,可以使用组件,提高程序的可读性、易维护性,降低维护成本
- 1 定义组件html文件
- 2 在具体html文件中,用include对组件进行引用 基本语法,{%include ' 引用组件的html文件名称 '%}
- simple_tag
- 1调用python内置函数
- {{ 参数 | 内置函数:参数 }}
- 2自定义函数
- a. app下创建templatetags目录
- b. 创建py文件
- c. 导入模块 from django import template from django.utils.safestring import mark_safe 创建template对象,register 继承自template.Library
- d. 创建自定义函数,加装饰器 @register.simple_tag
- e. settings中注册当前app
- f.在引用文件顶部导入函数文件 { % load 函数文件名 % }
- g. 执行自定义函数 { % 函数名 参数1 参数2 …… % }
- 在创建函数上面的加的装饰器,还可以是@register.filter 此时,调用函数的时候格式类似调用python内置函数,{{参数|函数名:数字参数}} 当传的参数较多时,用字符串, {{参数 | 函数名:“参数二,参数三,”}}。这种方式的缺点是,参数数量有限制,函数名后最多放两个参数,并且元素之间不能有空格。有点是能作为if判断条件使用
- 1调用python内置函数
- jquery中的Ajax基本操作
- 1 设置绑定ajax的标签, 例如, <a id="ajax_test">我是ajax构造提交</a>
- 2 在视图中构建ajax后台函数,
- 3, 在路由urls中绑定url ,指向后台ajax函数
- 4,在html中给设置的ajax标签,绑定动作事件,及url,type,data,datatype,sucess等,例如
-
1 $('#ajax_test').click(function(){ 2 $.ajax({ 3 url:"/ajaxTest/", 4 type:'POST', 5 data:{'hostname':$("#hostname").val(),"ip":$("#ip").val(),"port":$("#port").val(),"b_id":$("#b_id").val()}, 6 dataType:"JSON", 7 success:function(redata){ 8 if(redata=='ok'){ 9 location.reload(); 10 }else{ 11 alert(redata) 12 } 13 } 14 }) 15 })
- 其中提交的type,有GET,POST,JSON等类型
- data的数据可以用serialize打包发送。 例如: data:$(通过class或id等找到form标签).serialize()
- 如果发送的数据中,有多选的,例如select(multiple) 、checkbox等,需要在ajax参数中 设置 traditional:true ,这样,多选的数据会打包成列表发送至后台,后台函数取这类打包成列表的值得时候,需要用getlist。
- ajax操作,后台如果是return redirect,无法接收到数据。如果是return HttpResponse 可以顺利的通过JSON序列化与反序列化进行功能对接,当return render时,后台返回的页面内容也是字符串形式,不能自动执行,需要进一步处理。
- 当使用ajax时,需要跳转的情况下,可以在接收完后台数据后,利用,location reload()进行页面刷新 、location.href=" "跳转至下一级页面,或者location.replace() 完成页面跳转
-
- 分页操作
- 方式一,直接在视图函数中,对内容进行切分。
- 1 获取内容列表及其长度
- 2 设定每页显示的信息的数量,页码显示数量等
- 3 根据设定的信息数量,切片出显示在当前页的信息
- 4 根据页码显示的设置,配置显示页码起始,形成标签文本
- 5 给页码的文本内容,贴上safe, views函数中给文本 mark_safe处理或者在html 用{ |safe} 默认的是不允许传输内容中包括html代码的,防止XSS攻击
- xss攻击:XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。比如这些代码包括HTML代码和客户端脚本。攻击者利用XSS漏洞旁路掉访问控制——例如同源策略(same origin policy)。这种类型的漏洞由于被骇客用来编写危害性更大的网络钓鱼(Phishing)攻击而变得广为人知。对于跨站脚本攻击,骇客界共识是:跨站脚本攻击是新型的“缓冲区溢出攻击“,而JavaScript是新型的“ShellCode”。
- 返回内容设置 renturn render()
- 方式二,将函数中的处理步骤,封装到模块的类中,实例化后,基于实例化的分页对象做处理。
- 方式一,直接在视图函数中,对内容进行切分。
- cookie与session
- cookie 本质上是保存在客户端浏览器上的键值对形式存储的一个文件,明显地降低了服务器端的信息存储压力。注意的是,如果一些敏感信息放在cookie中,那内容会容易被看见
- 常见应用及方法
- 在服务端通过用户请求,利用request.COOKIES 得到的是一个字典。可以用 request.COOKIES.get() 或者 request.COOKIES[ ] 取值
- 给用户返回信息的时候,可以进行cookie设置,例如 给用户返回的信息是 response=redirect('/index/') 设置cookie response.set_cookie("key","value") 提交返回信息 return response
- cookie常用参数
- key 键
- value 值
- max_age 设置超时时间(以秒为单位),默认是None 例如, res.set_cookie("user111",'val', max_age=10)
- expires 超时时间(是datetime类型) 例如,设置保持登录到具体时间点 exp_date = datetime.datetime.utcnow() + datetime.timedelta(seconds= **) res.set_cookie("user111","value",expires=exp_date)
- path 设置cookie生效路径,默认是“/” 表示根路径,根路径的cookie可以被任何url页面访问
- domain 默认是None,可以设置cookie生效的域名
- secure 默认是False,管理https传输
- httponly 只能http协议传输,无法被JavaScript获取(除非是底层抓包等特殊处理)
- salt 用于给cookie加密,加密和解密的salt必须一致
- 常见应用及方法
- session是保存在服务器端的键值对文件。
- session的创建细节,实际上是由django自动完成的,由1 生成随机字符串 2 给客户浏览器写入cookie 3 把字符串存到session中 4在随机字符串对应的字典中完成相关内容的设置
- session是依赖于cookie的
- session创建,在request中,直接设置。 request.session['username']=user**
- 在使用session之前,必须要执行一遍migarate。在django中,默认情况下,session是保存在数据库中的
- 调取session的时候 request.session['username']
- session常用操作和方法
- request.session['user'] 获取session,键为‘user’的值,不存在,则报错
- request.session.get('user',None) 获取session,键为‘user’的值,不存在时,返回默认值,这里是None
- request.session['user']='abc111' session中‘user’ 如果存在,则改,不存在则创建
- request.session.setdefault('user','abc222') 单纯新建,如果有‘user’,不操作
- del request.session['user'] 删除键值对‘user’
- reques.session.clear() 删除当前登录的session所有信息,注销用
- request.session.keys()
- request.session.values()
- request.session.items()
- request.session.iterkeys()
- request.session.itervalues()
- request.session.iteriterms()
- request.session.session_key 获取用户的session中随机字符串
- request.session.clear_expired() 清除session中失效日期小于指定日期的数据,默认是当前时间
- request.session.exists('session_key') 检查用户session随机字符串,在数据库中是否存在(是否注销)
- request.session.delete('session_key') 删除当前用户的所有session数据,注销
- request.session.set_expiry(value) 设置超时时间,默认django的session超时时间是2周
- 如果value是整数,表示超时时间是读秒
- 如果是detetime或timedelta,表示具体的超市时间点
- 如果是0,用户关闭当前浏览器,session失效
- 如果是None, 当前的session的有效期依赖于全局session
- 配置settings.py引擎配置和通用配置 ,设置或修改一些默认操作。
- SESSION_ENGINE='django.contrib.sessions.backends.db' 配置session的引擎,默认即数据库
- 修改session引擎,至缓存。 设置引擎为cache SESSION_ENGINE='django.contrib.sessions.backends.cache' 设置要链接的cache SESSION_CACHE_ALIAS='default' 设置cache的链接 CACHE={ ‘default’:{‘BACKED’:'django.core.cache.backends.memcached.MemcachedCache' 'LOCATION':[IP地址列表] } ‘db1’:{‘BACKED’:'django.core.cache.backends.memcached.MemcachedCache' 'LOCATION':[IP地址列表] } }
- 修改session引擎,至文件。 设置引擎为file SESSION_ENGINE='django.contrib.sessions.backends.file' 设置要保存的文件路径,不设置的话会创建一个临时目录 SESSION_FILE_PATH=os.path.join(BASE_DIR,'cache')
- 引擎可以设置为数据库+缓存 引擎配置为 SESSION_ENGINE='django.contrib.sessions.backends.cache_db' 缓存相关设置 链接 + cache设置
- 可以设置为加密cookie_Session,此时session信息加密保存在客户端 引擎配置:SESSION_ENGINE='django.contrib.sessions.backends.signed_cookies'
- 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失效日期,默认两周即1209600秒
- SESSION_COOKIE_BROWSER_CLOSE=False 是否关闭浏览器即使得session失效
- SESSION_COOKIE_REQUEST=False 是否每次请求都重新保存session,默认是不保存
- SESSION_ENGINE='django.contrib.sessions.backends.db' 配置session的引擎,默认即数据库
- cookie 本质上是保存在客户端浏览器上的键值对形式存储的一个文件,明显地降低了服务器端的信息存储压力。注意的是,如果一些敏感信息放在cookie中,那内容会容易被看见
- CSRF简介及中间件设置介绍
- CSRF与跨站请求伪造简介
- csrf原理
- 跨站请求伪造
- 无csrf时存在的隐患(csrf存在的意义)
- 一般情况下,当request.mehtod是get,head,options,trace等方式的时候,可以不加csrf_token
- csrf设置
- 全局设置 settings中,找中间件 MIDLEWARE[
'django.middleware.csrf.CsrfViewMiddleware'
] - 局部设置 用装饰器对视图函数进行设置 单独加加csrf设置 @csrf_protect 单独取消csrf设置 @csrf_exempt
- 全局设置 settings中,找中间件 MIDLEWARE[
- form表单提交与csrf
- ajax提交与csrf
- 单个ajax请求时,设置
- 对页面中所有ajax请求统一设置
- 中间件 MIDDLEWARE
- 中间件,也称管道或handler,在settings文件中,本质上是一个继承自 django.utils.deprecation 中的MiddlewareMixin类的 类的集合
- 中间件的执行过程自上而下,逐一执行每个中间件的类函数process_request ,如果中间都能通过的话,最终调用views视图函数,收到视图函数的反馈信息以后,再反向逐一执行process_response 如果中间都能通过的话,最后将信息反馈给发起请求的客户。如果在某一步的process_requestt或process_response 中出现异常,或不能通过,会按照不同版本的具体要求(有的版本会在本层次直接返回,有的版本会跳转到最后一层中间件的process_response然后返回),逐层逐层反馈最后将信息发回请求发起端。
- 中间件的实用性极高,一般用于对整个函数系统的同一设置或限制
- 使用自定义中间件,过程
- 首先,创建包,构建中间件的py文件
- 在py文件中,从django.utils.deprecation 中导入MiddlewareMixin,然后根据需要继承MiddlewareMixin构建自定义中间件的类和函数
- 最后,在settings的MIDDLEWARE中注册自定义的中间件
- 中间件中常用的基本方法有
- process_request(sef,request) *****
- process_view(self,request,callback,callback_args,callback_kwargs) *****
- process_template_response(self,request,response) *
- process_exception(self,request,exception) ***
- process_response(self,request,response) *****
- CSRF与跨站请求伪造简介
- 缓存
- 实际上大部分web框架中是没有缓存的。但django支持缓存,由于django是动态web框架,每次请求都会去进行相应操作,当程序访问量大时压力明显,最简单的方式就是利用缓存。在django中支持的缓存方式包括测试缓存、内存缓存、文件缓存、数据库缓存以及通过memcache使用远程机器缓存。不同的缓存形式的配置,基本上是以修改缓存引擎为主。
- 缓存的5中配置方式:
- 测试缓存
- 内存缓存
- 文件缓存
- 数据库缓存
- memcache缓存
- 缓存的其他配置(通用配置)
- 缓存的3中常见应用,使用的优先级可以通过请求生命周期来理解,全站缓存优于视图函数缓存优于局部缓存,
- 全局缓存
- 视图函数缓存
- 模板中局部缓存
- 缓存参考:www.cnblogs.com/wupeiqi/articles/5246483.html
- 信号
- 信号的功能及应用场景
- 内置信号
- 内置信号类型
- 内置信号的使用
- 创建py文件,导入内置信号,信号触发动作、函数构造及设置,py文件导入__init__文件自动加载
- 自定义信号
- 1 定义信号
- 引入 django.dispatch
- 实例化自定义信号 信号名=dijango.dispatch.Signal(providing_args=["toppings","size"]) 括号中为必要的触发参数,可以自定义
- 2 注册触发信号设置
- 定义触发动作、函数
- 在视图函数views中,从py文件里导入自定义的信号
- 手动触发信号, 信号名.send(sender=" ",toppings=参数1,size=参数2)
- 3在信号中注册函数(定义、优化触发动作、函数)
- 1 定义信号
- django中的 Form 组件
- form组件参考 https://www.cnblogs.com/wupeiqi/articles/6144178.html
- django的form组件,使用时,是以继承forms.Form类,来自定义form类。
- 其中,类里面可以定义字段(主要功能,创建前端输入区域、输入内容格式验证),基本语法, 字段=fields.字段类型(参数设置,插件设置,错误提示)
- 常用字字段有: Charfield,RegexField,IntegerField,EmailField
- 常用参数有:required=True/False 设置是否可以为空; max_length最大长度; min_length 最短长度 ; label 设置label ; disabeld=False/True 设置是否可编辑; label_suffix 设置label内容后缀; help_text 帮助提示信息
- 主要内置字段和常用参数:
-
1 Field 2 required=True, 是否允许为空 3 widget=None, HTML插件 4 label=None, 用于生成Label标签或显示内容 5 initial=None, 初始值 6 help_text='', 帮助信息(在标签旁边显示) 7 error_messages=None, 错误信息 {'required': '不能为空', 'invalid': '格式错误'} 8 show_hidden_initial=False, 是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直) 9 validators=[], 自定义验证规则 10 localize=False, 是否支持本地化 11 disabled=False, 是否可以编辑 12 label_suffix=None Label内容后缀 13 14 15 CharField(Field) 16 max_length=None, 最大长度 17 min_length=None, 最小长度 18 strip=True 是否移除用户输入空白 19 20 IntegerField(Field) 21 max_value=None, 最大值 22 min_value=None, 最小值 23 24 FloatField(IntegerField) 25 ... 26 27 DecimalField(IntegerField) 28 max_value=None, 最大值 29 min_value=None, 最小值 30 max_digits=None, 总长度 31 decimal_places=None, 小数位长度 32 33 BaseTemporalField(Field) 34 input_formats=None 时间格式化 35 36 DateField(BaseTemporalField) 格式:2015-09-01 37 TimeField(BaseTemporalField) 格式:11:12 38 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 39 40 DurationField(Field) 时间间隔:%d %H:%M:%S.%f 41 ... 42 43 RegexField(CharField) 44 regex, 自定制正则表达式 45 max_length=None, 最大长度 46 min_length=None, 最小长度 47 error_message=None, 忽略,错误信息使用 error_messages={'invalid': '...'} 48 49 EmailField(CharField) 50 ... 51 52 FileField(Field) 53 allow_empty_file=False 是否允许空文件 54 55 ImageField(FileField) 56 ... 57 注:需要PIL模块,pip3 install Pillow 58 以上两个字典使用时,需要注意两点: 59 - form表单中 enctype="multipart/form-data" 60 - view函数中 obj = MyForm(request.POST, request.FILES) 61 62 URLField(Field) 63 ... 64 65 66 BooleanField(Field) 67 ... 68 69 NullBooleanField(BooleanField) 70 ... 71 72 ChoiceField(Field) 73 ... 74 choices=(), 选项,如:choices = ((0,'上海'),(1,'北京'),) 75 required=True, 是否必填 76 widget=None, 插件,默认select插件 77 label=None, Label内容 78 initial=None, 初始值 79 help_text='', 帮助提示 80 81 82 ModelChoiceField(ChoiceField) 83 ... django.forms.models.ModelChoiceField 84 queryset, # 查询数据库中的数据 85 empty_label="---------", # 默认空显示内容 86 to_field_name=None, # HTML中value的值对应的字段 87 limit_choices_to=None # ModelForm中对queryset二次筛选 88 89 ModelMultipleChoiceField(ModelChoiceField) 90 ... django.forms.models.ModelMultipleChoiceField 91 92 93 94 TypedChoiceField(ChoiceField) 95 coerce = lambda val: val 对选中的值进行一次转换 96 empty_value= '' 空值的默认值 97 98 MultipleChoiceField(ChoiceField) 99 ... 100 101 TypedMultipleChoiceField(MultipleChoiceField) 102 coerce = lambda val: val 对选中的每一个值进行一次转换 103 empty_value= '' 空值的默认值 104 105 ComboField(Field) 106 fields=() 使用多个验证,如下:即验证最大长度20,又验证邮箱格式 107 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) 108 109 MultiValueField(Field) 110 PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用 111 112 SplitDateTimeField(MultiValueField) 113 input_date_formats=None, 格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y'] 114 input_time_formats=None 格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] 115 116 FilePathField(ChoiceField) 文件选项,目录下文件显示在页面中 117 path, 文件夹路径 118 match=None, 正则匹配 119 recursive=False, 递归下面的文件夹 120 allow_files=True, 允许文件 121 allow_folders=False, 允许文件夹 122 required=True, 123 widget=None, 124 label=None, 125 initial=None, 126 help_text='' 127 128 GenericIPAddressField 129 protocol='both', both,ipv4,ipv6支持的IP格式 130 unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用 131 132 SlugField(CharField) 数字,字母,下划线,减号(连字符) 133 ... 134 135 UUIDField(CharField) uuid类型 136 ...
-
-
插件设置,常用格式 例如,widget=widgets. PasswordInput(attrs={'class':'c01'}) widget=widgets.Textarea(attrs={'class:c002'}) widget=widgets.Select(choices=models.Classes.objects.values_list('id','title'))
- 主要插件
-
1 TextInput(Input) 2 NumberInput(TextInput) 3 EmailInput(TextInput) 4 URLInput(TextInput) 5 PasswordInput(TextInput) 6 HiddenInput(TextInput) 7 Textarea(Widget) 8 DateInput(DateTimeBaseInput) 9 DateTimeInput(DateTimeBaseInput) 10 TimeInput(DateTimeBaseInput) 11 CheckboxInput 12 Select 13 NullBooleanSelect 14 SelectMultiple 15 RadioSelect 16 CheckboxSelectMultiple 17 FileInput 18 ClearableFileInput 19 MultipleHiddenInput 20 SplitDateTimeWidget 21 SplitHiddenDateTimeWidget 22 SelectDateWidget
- 常用选择插件设置距离
-
1 # 单radio,值为字符串 2 # user = fields.CharField( 3 # initial=2, 4 # widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),)) 5 # ) 6 7 # 单radio,值为字符串 8 # user = fields.ChoiceField( 9 # choices=((1, '上海'), (2, '北京'),), 10 # initial=2, 11 # widget=widgets.RadioSelect 12 # ) 13 14 # 单select,值为字符串 15 # user = fields.CharField( 16 # initial=2, 17 # widget=widgets.Select(choices=((1,'上海'),(2,'北京'),)) 18 # ) 19 20 # 单select,值为字符串 21 # user = fields.ChoiceField( 22 # choices=((1, '上海'), (2, '北京'),), 23 # initial=2, 24 # widget=widgets.Select 25 # ) 26 27 # 多选select,值为列表 28 # user = fields.MultipleChoiceField( 29 # choices=((1,'上海'),(2,'北京'),), 30 # initial=[1,], 31 # widget=widgets.SelectMultiple 32 # ) 33 34 35 # 单checkbox 36 # user = fields.CharField( 37 # widget=widgets.CheckboxInput() 38 # ) 39 40 41 # 多选checkbox,值为列表 42 # user = fields.MultipleChoiceField( 43 # initial=[2, ], 44 # choices=((1, '上海'), (2, '北京'),), 45 # widget=widgets.CheckboxSelectMultiple 46 # ) 47 在使用选择标签时,需要注意choices的选项可以从数据库中获取,但是由于是静态字段 ***获取的值无法实时更新***,那么需要自定义构造方法从而达到此目的。
-
-
- 异常信息设置, error_message={异常信息:反馈内容} 例如,error_message={'required':'信息不能为空',‘min_length’:'不能小于长度** ',‘max_length’:' 长度不能超过** '}
- 在定义的视图函数中,实例化定义的form类
- 把实例化的form对象obj(可以不传任何参数进去,此时新建空表,也可以先定义一个字典,键取自定义的form类值为设定的初始化值,然后把字典用initial实例化对象的时候传进去,这样建立的表单里会有初始化的默认值) ,render回前端,可生成form表单
- 前端的html中,可以通过替换obj中的 字段,生成表单内容,可以把出错的提示信息放一块 , 例如, <p> {{obj.user}} {{obj.errors.user.0}} </p>
- 也可以进一步简化,不单独替换具体字段,而是用obj对象的方法 {{obj.as_p}} 、 {{obj.as_ul}} 或者 <table> {{obj.as_table}}</table>
- 实例化对象,把request.POST 传进去,可用对象验证输入信息、接收验证信息,并返回对应的错误信息
- 此时 obj.is_valid() 可验证数据是否全都有效合法, obj.clean_data 可接收前端传过来的信息,以字典形式存储 obj.errors 可搜集错误信息,整体以字典形式存储,字段为键,对应的错误信息以列表形式存储作为字典的值
- 如果, obj.is_valid() 数据通过验证即为True,根据需要选择反馈内容 ; 如果是False,则render的时候,把obj直接传回去,这时,obj中既有前端之前的输入信息,也有错误信息和对应的提示内容
- 把实例化的form对象obj(可以不传任何参数进去,此时新建空表,也可以先定义一个字典,键取自定义的form类值为设定的初始化值,然后把字典用initial实例化对象的时候传进去,这样建立的表单里会有初始化的默认值) ,render回前端,可生成form表单
- 验证重要节点,
- is_valid——》每个字段的内置正则+clean_字段——》clean(__all__)——》_post_clean
- clean_data
- errors
- ModelForm
- model+form,可以实现验证也同时可以数据操作
- 基本功能
- 生成html标签:class Meta:
- 页面显示,生成时带默认值。在创建时, mf = ***ModelForm(instance=ModelObj)
- 加额外的标签或定制字段, is_rmb = Ffields.CharField(widget=Fwidgets.CheckboxInput())
- 各种验证 is_valid() …… ,类似于form中的验证节点
- 保存,直接 mf.save() ,或者 instance = mf.save(False) instance.save() my.save_m2m()