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对象