Django 学习笔记
Django学习笔记:
###查 models.UserInfo.objects.all() models.UserInfo.objects.all().values('user') #只取user列 models.UserInfo.objects.all().values_list('id','user') #取出id和user列,并生成一个列表 models.UserInfo.objects.get(id=1) models.UserInfo.objects.get(user='yangmv') ###增 models.UserInfo.objects.create(user='yangmv',pwd='123456') obj = models.UserInfo(user='yangmv',pwd='123456') obj.save() dic = {'user':'yangmv','pwd':'123456'} models.UserInfo.objects.create(**dic) ###删 models.UserInfo.objects.filter(user='yangmv').delete() ###改 models.UserInfo.objects.filter(user='yangmv').update(pwd='520') obj = models.UserInfo.objects.get(user='yangmv') obj.pwd = '520' obj.save() ### models.DateTimeField 日期类型 datetime 参数, auto_now = True :则每次更新都会更新这个时间 auto_now_add 则只是第一次创建添加,之后的更新不再改变。 ###表结构修改 新增加的字段,设置允许为空。生成表的时候,之前数据新增加的字段就会为空。(null=True允许数据库中为空,blank=True允许admin后台中为空) 新增加的字段,设置一个默认值。生成表的时候,之前的数据新增加字段就会应用这个默认值 ### models.ImageField 图片 models.GenericIPAddressField IP ip = models.GenericIPAddressField(protocol="ipv4",null=True,blank=True) img = models.ImageField(null=True,blank=True,upload_to="upload") ### 选择下拉框 choices class UserInfo(models.Model): USER_TYPE_LIST = ((1,'user'),(2,'admin'),) user_type = models.IntegerField(choices=USER_TYPE_LIST,default=1) ###动态路由 url(r'^getxxxlist'/(?P<customerid>\d+)/',view.get_goodlist,name='get_goodlist') django目录介绍: manage.py 是DJANGO用于管理本项目的命令行工具,之后进行站点运行,数据库自动生成等都是通过该文件完成。 file/init.py 告诉python 该目录是一个python包,暂无内容,后期一些工具的初始化可能会调用 file/setting.py DJANGO项目的配置文件,默认状态其中定义了奔项目引用的组件,项目名,数据库,静态资源等。 file/urls.py 维护项目的url路由映射,即定义当客户端访问路由时那个模块进行相应 file/wsgi.py 定义WSGI的接口信息,主要用于服务器继承,通常本文件生成后无需改动。 python manage.py runserver [ip:port] 迁移数据,pyCharm 连接数据库 迁移的概念:就是将模型映射到数据库的过程 生成迁移:python manage.py makemigrations 执行迁移:python manage.py migrate 介绍DateBase模块,可以直接连接操作数据库sqlite和MySQL ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', 'USER':'root', 'PASSWORD':'rock1204', 'HOST':'127.0.0.1', 'PORT':'3306', 基本模块 模板实际就是已经写好的HTML页面 在views中取加载渲染模板 1. from django.template import loader template = loader.get_template('xxx') return HttpRespones(template.render()) 2. return render(request,'xxx') ##模板配置 -两种 在APP中进行模板配置 只需要APP的根目录创建templates文件夹即可 如果想让代码自动提示,我们应该标记文件夹为模板文件夹 在项目目录中进行模板配置 需要在项目目录中创建templates文件夹并标记 需要在setting中进行注册 在开发中使用第二种 模板可以继承,复用 ## 路由优化配置 项目如果逻辑过于复杂,可以进行拆分 拆分为多个app 继续拆分路由器 urls 在APP中创建自己的urls urlpatterns路由规则列表 在跟urls中进行子路由的包含 子路由的使用 根路由规则 + 子路由的规则 ## models 使用了ORM技术 Object Relational Mapping对象关系映射 将业务逻辑进行了一个解耦合 object.save() object.delete() 关系型数据库 DDL 通过models定义实现 数据库表的定义 数据操作 增删改查 存储 model.save() 查询 查所有 model.object.all() 差单个 model.object.get(pk = number) 更新 基于查询的 查好的对象,修改属性,然后save() 删除 基于查询的 调用delete() ## 连接Mysql驱动 mysqlclient python2,3都能够直接使用 致命缺点 对mysql安装有要求,必须指定位置存在配置文件 python-mysql python2支持很好 python3 不支持 pymysql Python2,python3都支持 他还可以伪装成前面的库 在__init__文件中: import pymysql pymysql.install_as_MySQLdb() 表关系: 1:1 1:M M:N Model 在企业开发中,我们通常都是从数据开始开发的 ORM 对象关系映射 可以理解为翻译机 核心思想,解耦合 将业务逻辑和SQL进行了解耦 数据库中的数据类型 字符串 数字 日期时间 模型过滤 filter exclude 可以连续使用 链式调用 Person.objects.filter().filter().exclude()... 方法 对象方法 可以调用对象的属性,也可以调用类的属性 类方法 不能调用对象属性,只能调用类属性 静态方法 啥都不能调用,不能获取对象属性,也不能获取类属性 结构标签 block 块 用来规划我们的布局(挖坑) 首次出现,代表规划 第二次出现,代表填充以前的规划 第三次出现,代表覆盖以前的规划, 如果不想规划,可以添加{{block.super}} 这样就实现了增量式操作 extends 继承 可以获取父模板中的所有结构 block + entends 化整为零 include 包含 可以将页面作为模块,嵌入到其他页面中 include + block 组合使用 三个标签都可以混合使用 能用block+extends搞定的 尽量不用Include 如果我们继承自一个父模块,子模块自己直接重写页面结构是不生效的,只能在既有坑中填写相应的内容 双R Request 内置属性 method path GET 类字典结构 key允许对应多个值 POST META 各种客户端元信息 REMOTE_ADDR 远程访问IP Response 爬虫 模拟人去请求数据 提取数据 存储数据 核心内容 数据爬取 数据提取 数去存储 属性 content 返回的内容 charset 编码格式 status code 响应状态码(200,3xx,500...) content-type mime类型 方法 Init 初始化 write() 直接写入 flush() 冲刷缓冲区 set cookie delete cookie 删除cookie JSON(ajax数据响应) JsonResponse() jsonObject {} key- value jsonArray [ ] 列表中可以是普通数据类型,也是可以jsonObject jsonObject和jsonArray可以嵌套 给移动端的json 给AJAX 前后端 DRF Google hrome jsonFomatter jsonView HttpRespones(HTML页面响应) HttpResponseRedirect 重定向,暂时 302 简写redirect jsonRespones 以Json格式返回数据 重写了__init__,序列号json数据,指定content_type为application/json 重定向,永久性 301 cookie的设置:response.set_cooie('username',username,max_age) cookie的获取:response.COOKIES.get('username') cookie的加密:response.signed_cookie('content',content,'xxx') cookie的解密:response.get_signed_cookie('content',salt='xxx') cookie 删除:response.delete_cookie('content') 服务器session获取回话的值:response.get(key) 服务器session清除所有回话:response.clear() 服务器session清空 :response.session.flush() #Session 服务端回话技术 数据存储在服务器中 默认Session存储在内存中 Django中默认会把Sessions持久化到数据库中 Django中Session的默认过期时间是14天 主键是字符串 数据是使用了数据安全 使用的BASE64 在前部添加了一个混淆串 Session依赖于Cookie Token 服务端会话技术 自定义的Session 如果Web页面开发中,使用起来和Session基本一致 如果使用在移动端或客户端开发中,通常以json形式传输,需要移动端子机存储Token,需要获取token关联数据的时候,主动传递token CSRF 放跨站攻击 防止恶意注册,确保客户端是我们自己的客户端 使用cookie中csrftoken进行验证,传输 服务器发送给客户端,客户端将cookie获取过来,还要进行编码转换(数据安全) 如何实现 在我们存在csrf_token标签的页面中,响应会自动设置一个cookie ,csrf_token 当我们提交的时候,会自动验证csrf_token 验证通过,正常执行以后流程,验证不通过,直接403 ###迁移 分两步实现 生成迁移文件 执行迁移文件 迁移文件的生成 根据models文件生成对应的迁移文件 根据models和已有迁移文件差别 生成新的迁移文件 执行迁移文件 先去迁移记录查找,那些文件为迁移过 app_label+迁移文件名字 执行未迁移的文件 执行完毕,记录执行的迁移文件 重新迁移 删除迁移文件 删除迁移文件产生的表 删除迁移记录 ####模型关系 1:1 应用场景 用于复杂表的拆分 拓展新功能 Django中OneToOneField 使用的时候,关系声明还是有细微差别的 实现 使用外键实现 对外键添加了唯一的约束 数据删除 级联表 主表 从表 谁声明关系谁就是从表 在开发中如何确认主从 当系统遭遇不可避免的灾害时,只能保留一张表,这个表就是你的主表 默认特性 从表数据删除,主表不受影响 主表数据删除,从表数据直接删除 1:M ForeignKey 主从获取 主获取从 隐藏属性 级联模型_set student_set Manage的子类 all filter exclude Manager上能使用的函数都能使用 从获取主 显示属性 M: N 实际上最复杂 开发中很少直接使用多对多属性,而是自己维护多对多的关系 产生表的时候回产生单独的关系表 关系表中的存储关联表的主键,通过多个外键实现的 多个外键值不能同时相等 级联数据获取 从获取主 使用属性,属性是一个Manage子类 主获取从 隐藏属性 也是Manage子类,操作和从操作完全一样 级联数据 add remove clear set ManyPelatedManager 函数中定义的类 并且父类是一个参数 动态创建 ###模型继承 Django中模型支持继承,默认继承是讲通用字段放在父表中,特定字段放在自己的表中,中间使用外键连接 关系型数据库关系越复杂,效率越低,查询越慢 父类表中也会存在过多的数据 使用元信息来解决这个问题: 使模型抽象化,抽象化的模型就不会在数据库中产生映射了 子模型映射的表中直接获取父模型中的字段 class Meta: abstract = True ###在企业开发中 model =>sql 可以使用 sql=>model 反向生成django模型 python manage.py inspectdb 根据数据库存在的库表,对应生成相应的模型 可以直接根据表生成模型 元信息中包含一个属性 manage= False 如果自己的摸个模型不想被迁移系统管理,也可以使用manage = Flase进行声明 ### 图片上传 request.FILES.get('icon') with open("/path/icon.jpg",'wb') as save_file: for part in icon.chunks(): save_file.write(part) save_flush() 支持时间格式化 %Y %m %d 生成对应的时间文件层级目录 ### 缓存 提升服务器响应速度 将执行过的操作数据存储下来,在一定时间内,再次获取数据的时候,直接从缓冲中获取 比较理想的方案,缓存使用内存级缓存 django 内置缓存框架 创建缓存表:python manage.py createcachetable[table_name] 缓存配置: CACHES = { 'default':{ 'BACKEND':'django.core.cache.backends.db.DatabaseCache', 'LOCATION':'my_cache_table', 'TIMEOUT':'60', } } 缓存使用 在试图中使用(使用最多的场景) @cache_page() time秒 60*5缓存5分钟 cache缓存配置,默认为default参数 key_prefix:前置字符串 自定义Cache: def news(request): cacheResult = cache.get('news') //通过Key获取cache的值 if cacheResult : return HttpResponse(cacheResult) //如果cache存在就直接返回,如果不存在就获取 newslist = [] for intem in range(20): newslist.append('最近美国死了%d w人'%intem) data={ 'news_list':newslist } response = render(request,'news.html',context=data).content //设置获取的数据格式 为render内容 cache.set('news',response,timeout = 30) //设置cache值 key,value,timeout:如果不设置就默认为系统设置的值 return HttpResponse(response) ###AOP中间件 实现统计功能 统计IP 统计浏览器 from django.utils.deprecation import MiddlewareMixin class getView(MiddlewareMixin): def process_request(self,request): print(request.META.get('REMOTE_ADDR')) 实现权重控制 黑名单 白名单 实现反爬 反爬虫 控制搜索频率 if request.path == '/app/news/': result = cache.get(IP) if result : return HttpResponse('你的搜索过于频繁') cache.set(IP,IP,timeout = 10) 实现评率控制 1分钟内最多请求10次 result = cache.get(IP,[]) while result and time.time() - result[-1]>60: result.pop() if len(result)>10: return HttpResponse('别请求了爬虫') result.insert(0,time.time()) cache.set(IP,result,timeout = 60) 黑名单控制: result = cache.get(IP,[]) blanklist = cache.get('blank',[]) if IP in blanklist: return HttpResponse('黑名单凉了') while result and time.time() - result[-1]>60: result.pop() result.insert(0, time.time()) cache.set(IP, result, timeout=60) print(len(result)) if len(result)>30: blanklist.append(IP) cache.set('blank',blanklist,timeout = 60*60*12) return HttpResponse('你要凉了 爬虫') if len(result)>10: return HttpResponse('别请求了爬虫') 界面友好化 {% csrf_token %} 表单csrf口令 @csrf_exempt view函数csrf口令 ###中间件: 调用顺序 中间件注册的时候是一个列表 如果我们在切点出直接进行返回,中间件就会依次执行 如果我们直接进行了返回,后续中间件就不会执行了 切点: process_request : 统计,打印 优先级调用 (黑名单,白名单) 反爬,频率控制 (N时间段之内只能请求一次) 单位时间内最多访问次数(我们需要记录每次请求时间 数据结构 key-value value=[] 在判断单位时间请求次数的时候,判断的是列表长度 在判断之前进行简单的数据清洗 process_view : CSRF 首先判断两种豁免条件 判断请求是否安全 POST请求如何验证CSRF 在request.POST.get('csrftokenmiddleware') 验证和请求对应的token是否正确 process_response : 跨域处理 ip 和端口不一致,只有一个不一样的就是不一样 跨域的行为校验是浏览器行为 实现跨域 服务器端添加属性 允许所有域名访问 在客户端伪装 对响应进行统一处理 process_template_response process_exeption : 错误统一处理 切面 ###分页器: 原生分页器方法: page = int(request.GET.get('page',1)) size = int(request.GET.get('size',10)) student = Student.objects.all()[size*(page-1):page*size] paginator分页器方法: page = int(request.GET.get('page', 1)) size = int(request.GET.get('size', 10)) student = Student.objects.all() paginator = Paginator(student,size) page_object = paginator.page(page) 或者: page_object = Paginator(Student.objects.all(),size).page(page) 属性: count 对象总数 num_pages:页面总数 page_range:页码列表,从1开始 方法:Page(整数):获得一个Page对象