python学习笔记
DAY1:
1.计算机基础
CPU:相当于人的大脑,用于计算
内存:成本高,断电即消失
硬盘:固态硬盘,机械硬盘(留声机),存储数据
操作系统:用于操作各个部分
应用程序:.exe
2.python历史
python2 与python3的区别:python2的标准不规范,重复代码过多。python3同一标准,去除重复代码
3.python的环境
编译型:一次性将所有程序编译成二进制文件。缺点:开发效率低,不能跨平台。优点:执行速度快
解释型:当程序执行时,一行一行的编译成二进制。优点:开发效率高,可以跨平台,缺点:运行速度慢,python ,php等等
python是一门动态解释性的强类型定义语言
打印中文时:
python2x:默认编码方式是ascii码,在文件首行加#-*- encodidng:utf-8 -*-
python3x:默认编码方式是utf-8
4.变量:必须由数字、字母、下划线任意组合,且不能数字开头,不能是python中的关键字,不能是中文,和预留的字符;
int(str),只能把是数字的str转换成数字类型
5.常量:一直不变的量,一般用大写来表示,BIR_OF_DATE = 1949
6.注释
单行注释:#
多行注释:'''被注释内容''',"""被注释内容"""
Day2
1.pass:过,什么都不执行,但是回继续往下走。
2.while-else:如果有while循环体中有break,则跳出循环体且不执行else结果。
3.continue:跳出这次循环,不执行后面的代码,进入下一次循环。
4.input:输入的是字符串类型,如果需要的是整型,可以强制类型转换。
5.%是格式化输出的占位符,同时也可以作为转义字符适用于。
6.初始编码:
最开始:ascii最初作为美国本土的编码本,最高一位全是0,一共八位,只存字母。为了解决这个全球化文字问题,创建了一个万国码,unicode(一个字节表示英文,特殊字符,数字等等;最开始用2个字节来表示,不够用。后来用4个字节表示中文,特殊字符和数字
升级版:由于暂用太多内存,utf-8,一个中文用3个字节表示(中文约为9万个字);utf-8:最少用一个字节,8位表示一个英文。欧洲16位,两个字节;亚洲24位,三个字节。有三种格式:utf-8,utf-16,utf-32
gbk:国内使用,一个中文用2个字节来表示,不供其他国家使用,只能用于中文和ascii码。
7.运算符:
//,整除等于
Day3
1.什么是数据类型:
int 1,2,3用于计算
bool:True,False,用户判断
str:用引号引起来的字符,存储少量数据,便于操作
list: [ , , , ]可以循环查找内容,存储大量的数据
元祖:( , ) ,只读
dict:字典 {"name":"云姐","age":16,"二哥":[200,2000,200]}
集合:{1,23,45,'shegnwu'}
2.int
i.bit_length(),计算数字对应的二进制位是多少
3.str倒着取数切片的时候,要加步长,且步长为负数,比如-1
4.字符串操作:
首字母大写:capitalize()
全部变成大写:upper(),对数字没有影响
全部小写:lower()
大小写翻转:swapcase()
每个单词的隔开(特殊字符或者数字,空格)首字母大写:title()
设置字符串总宽度,并居中:center()
\t的补全8位或者16位:expandtabs()
元素的长度:len()
判断字符串的开头,是否以xxx开头的:startswith(相反的是endswith)
寻找对应元素所在的下标:find(),找不到返回-1
通过元素找索引,找不到报错
去字符串的前后空格:strip(),rstrip():删除右边,lstrip():删除左边
分割:split(),以xx分割为列表
format(),三种玩法
replace(),代替字符
is系列
isalnum(),字符串由数字组成
isalpha(),字符串由字母组成
isdigit(),字符串由数字组成
统计元素个数:count
5.在python编程时,碰到需要将字母转换成ascii码的:
ord(c):参数是长度为1的字符串,简称字符,当参数为统一对象时(unicodeobject),返回能代表该字符的统一编码,例如,ord('a')返回的整形数值97
chr(i):返回一个字符,字符的ascii码等于参数中的整形数值。例如chr(97)返回字符'a',该方法是ord()的反方法。参数必须是0-255的整形数值,否则会抛出valueError错误。
Day4
列表:(有序的)
#增加 append(),增加在最后,备注:凡是是字符,都可以使用多个点。
#插入,insert(index)
#extend,插入最后的,并且分解元素
#pop(),默认删除最后一个
#remove(),按元素删除
#clear(),清空列表
#del,删除列表
#len(),计算改列表有多少个元素
#count(value),返回value在列表出现的次数
#index(value),返回value的索引
#正向排序,sort()从小到大排序
#倒向排序,sort(True),从大到小排序
#反转,reverser()
Day6
指示回顾:
dict: dic = {"name":"alex"}
增:dic['age'] = 21 存在就覆盖
dic.setdefault() 没有就增加
删除:pop() 按照Key删除,有返回值
clear
del dic['name']
popitem() 随机删除,返回的是元祖
改:update
查:
dic.keys()
dic.values()
dic.items()
for k,v in dic.items():
print(k,v)
dic.get(key,None) 没有查到,返回None
pycharm的快捷键:
代码快速运行:Ctrl+Shift+F10
换行:Shift+ Enter
快速查看文档:Ctrl + q
python2和python3的区别:
1.python2的print函数可以加括号也可以不加
2.python2的用户输入时raw_input()
3.python2中有一个时xrange()生成器
# = 赋值,== 比较值是否相等,is 比较,比较的时内存地址,id(内容)
编码:
ascii
A:00000010 8位 一个字节
unicode
A:00000000 00000001 00000010 00100100 32位 四个字节
中: 00000000 00100001 00000010 10000100 32位 四个字节
utf-8
A:00110010 8位 一个字节
中:10000001 00000010 10000100 24位 3个字节
gbk
A:00010010 8位 一个字节
中:00010010 10000100 16位 2个字节
1.各个编码之间的二进制,是不能互相识别的,会产出乱码。
2.文件的储存,传输不能是unicode,只能是(utf-8,utf-16,gbk,gb2312等)
py3:
str在内存中是用unicode 编码的。
bythes类型在内存用utf-8,gbk等编码
对于英文;
str: 表现形式:s = 'alex'
编码方式(内存存储):010101010 unicode
bytes:表现形式:s = b'alex'
编码方式: 00001111 utf-8 gbk
对于英文;
str: 表现形式:s = '中国'
编码方式(内存存储):010101010 010101010 010101010 010101010 unicode
bytes:表现形式:s = b'x\e91\e91\e01\e21\e32\e32' 三个字节表示一个字(utf-8)
编码方式: 00001111 00001111 00001111 utf-8 gbk(两个字节代表一个字)
#encode 编码,如何将str -- > bytes(),将用于文件的存储和传输
s = 'alex'
b = s.encode('utf-8')
print(b) # b'alex'
Day7
1.数据类型的回顾
range 顾头不顾尾,有序的长度,从0开始
2.循环字典的时候,再循环体删除键值对,会报错,因为字典是无序的
3.循环列表,用index去删除元素,报错
转化成bool值,是false的是,0 '' [] () set() {}
#如果元祖里面只有一个元素,而不加逗号,那此元素是什么类型,就是什么类型
聚合:set
集合:可变的数据类型,但是里面的元素是不可变的数据类型,无序,不重复,{}
不可变类型:常数,字符串,元祖
可变类型:列表,字典,自定义类对象,即可以增,删,改,查
Day8
1.文件操作
hello.txt
必须条件:
如果是写操作,w+,必须先写,再seek(0),再读,因为写的都是把源文件全部删除再写的。
1)文件路径:d:\hello.txt,绝对路径,从根目录开始
2)确定这个文件的编码方式是什么:utf-8,gbk
3)操作方式:只读,只写,追加,读写,写读........
以什么编码方式存储的文件,就是以什么编码方式打开
只读:r,rb:以bytes读出来,用于非文字的文件
只写:w,没有此文件,就会创建文件。如果有此文件,先将源文件的内容全部清除,再写。
追加:a,ab,a+
读写:r+ r+b
移动光标:seek()
Day9
1.今日内容
数据库--存储数据和信息用的,本质上和文件没有区别,增删改查更方便了。
前端--html
框架--django
函数--两周
面向对象和模块--二周
网洛编程--一周
并发编程--一周
文件处理:内存--硬盘
2.文件处理
read 一次性读,但是不知道在哪结束,视频,图片用rb按照字节读
readlines 一行一行全部读
for循环最好,每次一行读,内存只存一行,不会消耗过大
2.初始函数
返回值:1,没有返回值,没有return,返回None,只写return:结束一个函数的结束,return None:不常用
2,返回1个值,return xxxx,可以返回任何数据类型,只要返回就可以接收。如果在一个程序中有多个return,只执行第一个
3, 返回对个值,多个返回值,多用个变量接收,有多少个返回值就用多少变量接收。用一个变量接收,得到的是一个元组
实际参数:实参,在调用函数的时候使用(传递参数:传参)
形式参数:形参,在定义函数的时候使用
参数:
没有参数:定义函数和调用函数时括号里都不写内容
有一个参数:传什么就是什么
多个参数:
站在形参的角度:
位置参数:必须传
动态参数有两种:可以接收任意个参数
*args:接收的是按照传参的值,组织成一个元组
**kwargs:接收的是按照关键字传参的值,组织成一个字典
args必须在kwargs之前
顺序:位置参数,*args,默认参数,**kwargs
动态参数的另一种传参方式:
函数的注释
函数
1.函数的定义 def
2.函数的调用
3.函数的返回值 return
4.函数的参数
形参:
位置参数:必须传
*arg:可以接收任意多个位置参数
默认参数:可以不传
**kwargs:可以接收多个关键字参数
实参:按照位置传参,按照关键字传参
将列表转字符串:join()
Day10
1.函数:可读性强,复用性强
2.def 函数名():
函数体
return 返回值
3.所有的函数,只定义不调用就一定不执行,先定义后调用
4.如果默认参数的值是一个可变数据类型,那么每一次调用函数的时候,如果不传值就用公用这个数据类型的资源
#函数的进阶
1.命名空间
全局命名空间--我们写的代码但不是函数中的代码
是在程序从上到下被执行的过程中依次加载进内存的
放置了我们设置的所有变量名和函数名
局部命名空间--函数
就是函数内部定义的名字
当调用函数的时候,才会产生这个名称空间,随着函数执行的结束,这个命名空间就又消失了
内置命名空间--python解释器
就是python解释器一启动就可以使用的名字(print(),input(),list,tuple)存储在内置命名空间中
内置的名字在启动解释器的时候就被加载在内存里
在局部:可以使用全局、内置命名空间中的名字
在全局:可以使用内置命名空间中的名字,不能使用局部的名字
在内置:不能使用局部和全局的名字
当我们在全局定义了和内置名字空间中同名的名字时,会使用全局的名字
在正常的情况下,直接使用内置的名字
当我自己有得时候,我就不找我得上级要,如果没有,就找上一级要了,继续找,没有就报错
func --> 指向函数得内存地址
函数名() -->函数都调用
函数得内存地址() -> 函数得调用
多个函数拥有多个命名空间
1.作用域
全局作用域 -- 作用在全局 -- 内置和全局空间中得名字都属于全局作用域 --globals()
对于不可变数据类型 在局部可查看全局作用域中得变量,但是不能修改
如果想要修改,需要在函数体中一开始添加global声明
如果在一个局部内(函数)内声明了一个global变量,那么这个变量在局部得所有操作将对全局的变量有效
局部作用域 -- 作用在局部 --函数(局部名字空间中得名字属于局部作用域) --locals()
函数名:第一类对象
1.可在运行期创建
2.可用作为函数参数或返回值
3.可存入变量的实体
Day11
三元运算
变量 = 条件返回True的结果 if 条件 else 条件返回False的结果
装饰器的形成过程:
装饰器的作用:
六个原则:开放封闭原则
装饰器的固定模式
Day12
装饰器:
开发原则:开放封闭原则
装饰器的作用:在不改变原函数的调用方式的情况下,在函数的前后添加功能
装饰器的本质是:闭包函数
生成器 -- 迭代器
生成器函数 --本质上就是自己写的函数
只要含有yield关键字的函数都是生成器函数,而且不能和return共用,而且只能用于函数内部
学习资料:python核心编程(第二版)
Day13
复习:
函数的定义和调用
def 函数名(形参):
函数体
return 返回值
调用 函数名(实参)
站在形参的角度:位置参数,*args,默认参数(陷阱),**kwargs
站在实参的角度上:按位置传,按关键字传
返回值:没有返回值,返回一个值,返回多个值
接收返回值:没有返回值不接收,返回一个值用一个变量接收,返回多个值用一个变量或者对应数目的变量接收
闭包函数--在内部函数引用外部函数的变量
装饰器:--一定是闭包函数
装饰器的作用:在不改变原来函数的调用方式情况下,在这个函数的前后添加新的功能
完美的符合一个开发原则:开发封闭原则
对扩展是开方的
对修改是封闭的
基础装饰器
from functools import wraps
def wrapper(func):
@wraps(func)
def inner(*args,**kwargs):
'''在函数被调用之前添加的代码'''
ret = func(*args,**kwargs) # func是被装饰的函数,在这里被调用
'''在函数被调用之后添加的代码'''
return ret
return inner
@wrapper
func():
函数体
带参数的装饰器
@wrapper --> @warpper(argument)
三层嵌套函数
def outer(形参):
def wrapper(func):
def inner(*args,**kwargs):
'''在函数被调用之前添加的代码'''
ret = func(*args,**kwargs) # func是被装饰的函数,在这里被调用
'''在函数被调用之后添加的代码'''
return ret
return inner
@outer(True)
func():
函数体
多个装饰器装饰一个函数
俄罗斯套娃
迭代器:
print(dir([])) # 告诉我列表拥有的所有方法
可以for循环的:list dict set tuple enumerate([]) range(10) str f(文件句柄)
只要是能被for 循环的数据类型,就一定拥有__iter__方法
只要含有__iter__方法都是可迭代的 -- 可迭代协议
[].__iter__()迭代器,--> __next__ 通过next就可以从迭代器中一个一个的取值
迭代器协议 -- 内部含有__next__和__iter__方法就是迭代器
当我们遇到一个新的变量,不确定能不能for循环的时候,就判断它是否可迭代,是否有iter方法
迭代器的好处:
从容器类型中一个一个的取值,会把所有的值都取到
节省内存空间(range f )
迭代器并不会在内存中再占用一大块内存
而是随着循环,每次生成一个
每次next每次给我一个
生成器 -- 迭代器
生成器函数 -- 本质上是我们写的函数
Day14
判断是否是可迭代的,’__iter__' in dir(数据)
生成器的表现形式 -- 生成器函数 --生成器表达式
生成器特点:调用函数之后函数不执行,返回一个生成器,调用next方法的时候会取到一个值,直到取完最后一个,再执行next会报错
每一次执行g.__next__()就是从生成器中取值,预示着生成器函数中的代码继续执行
for 循环就是生成一个迭代器
从生成器中取值的几个方法:
next,for,数据类型的强制转换:占用内存
生成器的表达式
g = (i for i in range(10))
学习网址:www.cnblogscom/Eva-J/articles/7276790.html
[每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型] #遍历功能
[满足条件的元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件] # 筛选功能
各种推导式:生成器 列表 字典 集合
遍历操作
筛选操作
Day15
内置函数
locals() #返回本地作用域中的所有名字
globals() #返回全局作用域中的所有名字
迭代器相关的
迭代器.__next__()
next(迭代器)
迭代器 = iter(可迭代的)
迭代器 = 可迭代的.__iter__()
range(10) 可迭代的,不是迭代器
dir 查看一个变量拥有的方法
3>2==2,是True,分解为3>2以及2==2
‘A'的ascII是65 'a'的ascII是97
字符串比大小,比的是首字符大小。元祖不能比大小
Day16
数据类型:int bool float
数据结构:dict list tuple set str
匿名函数 lambda
Day17
带key的:max min filter map sorted
lambda 参数,参数2:返回值表达式
递归函数:
了解什么是递归函数 :在函数中调用自身函数,递归的最大深度是1000以内
能看到递归
能知道递归的应用场景
初始递归--
算法-- 二分查找算法
三级菜单 -- 递归实现
每一次调用函数的时候,都会开一个独立的内存空间
Recursion,递归
maximum recursion depth exceeded while calling a Python object,递归错误,超过了最大的递归深度
修改参数大小:import sys sys.setrecursionlimit(10000)
如果递归的次数太多,就不适合使用递归来解决问题
递归的缺点:占内存,优点:让代码变得更简单
算法:计算的方法:人脑复制,计算机简单
查找:找数据
排序
最短路径:百度地图
我们学习的算法都是过去时,了解基础的算法,才能创造出更好的算法
二分查找算法,必须处理有序的列表
只要写递归函数,必须要有结束条件
返回值:
不要只看到return就认为已经返回了,要看返回操作是在递归的第几层的时候发生的,然后返回给了谁
如果不是返回给最外层函数,调用者就接收不到。需要在分析,看如果把结果返回回来
递归:从结果往前推
Day18
任务:学习正则表达式,学习使用re模块来操作正则表达式
tool.chinaz.com/regex/
Day19
()分组,是对多个字符组整体量词约束的时候用的
分组是有优先的
split
| 从左到右匹配,只要匹配上就不继续匹配了,所以应该把长的放前面
[^] 除了字符组内的其他都匹配
在字符组里面,都是字符(本身的特殊字符不表达原来的意思)
惰性匹配:量词后面加问号
ret = search('\d(\w)+','awir149343jsdc')
ret = search('\d(?P<name>\w)+','awir149343jsdc')
找整个字符串,遇到匹配上的就返回,遇不到就None
如果有返回值ret.group()就可以取到值
取分组里面的内容:ret.group(1) / ret.group('name')
collections模块 python中的扩展数据类型
时间模块
random模块 随机数模块
os模块 和操作系统打交道的模块
sys模块 和Python解释器打交道的模块
序列化模块 python中的数据类型和str转换的模块
#有多少个模块--每个模块大概解决得问题
#把模块中得所有方法敲一遍 -- 写到博客
作业:
计算时间差
验证码
计算器
Day20
序列化模块
序列化 -- 转向一个字符串数据类型
序列 -- 字符串
数据存储(写文件)
网络上传输数据的时候
需要用到bytes类型,而bytes类型只有字符串有,所有如果要进行上面的操作,只能先将数据类型转化为字符串
从数据类型 --> 字符串的过程 序列化
从字符串 --> 数据类型的过程 反序列化
json *****:通用的序列化格式,只有很少的一部分数据类型能够通过json转化成字符串
pickle ****:所有的python的数据类型都可以转化成字符串形式
pickle序列化的内容只有python能理解
反序列化依赖代码
shelve ***:序列化句柄,使用句柄直接操作
json可序列化:数字,字符串,列表,字典,元组
dumps,loads直接操作内存的数据,dump和load往文件里面传数据
同一个模块,import多次,但是只执行一次
1.先从sys.modules里面查看是否已经被导入,如果没有导入,那就依据sys.path路径去寻找模块,找到了就导入
2.创建这个模块的命名空间
3.执行文件,把文件中的名字放到命名空间里
import sys
print(sys.modules.keys())
先导内置,扩展(django),自定义的
import 模块名
模块名.变量名 和本文件中的变量名完全不冲突
import 模块名 as 重命名的模块名 :提高代码的兼容性
import 模块1,模块2
from 模块名 import 变量名
直接使用 变量名 就可以完成操作
如果本文件中有相同的变量名会发生冲突
from 模块名 import 变量名字 as 重命名变量名
from 模块名 import 变量名,变量名
from 模块名 import *
将模块中的所有变量名都放到内存中
如果本文件中有相同的变量名会发生冲突
from 模块名 import * 和 __all__是一对的
没有这个变量,就会导入所有名字
如果有all,则会导入all内列举的
包 -- 一大堆模块的集合
__name__,在模块中 有一个变量__name__,
当我们直接执行这个模块的时候,__name__ == '__main__'
当我们执行其他模块,在其他模块中引用这个模块的时候,__name__ == '模块的名字'
Day24
面向对象编程
思想:角色的抽象,创建类,创建角色(实例化),操作这些实例
在一开始加载文件的时候,已经把类名存储在内存空间里面去了(包括静态属性和函数名)
组合:一个类的对象是另一个类对象的属性,什么有什么的关系
MySQL
DAY2:
上节回顾:
1.以ATM引出DBMS
2.安装MySQL
-服务端
-客户端
3.通信交流
-授权
-SQL语句
-数据库
create database db1 ?
drop database db1;
-数据表
先创建tb2
create table tb1(
id int not null auto_increment primary key,
name char(10),
department_id int,
constraint fk_1 foreign key (department_id) reference tb2(tid)
}engine=innodb default charset=utf8
用主键的原因是:保证数据的唯一性,主键的数据不能为空
一张表只能有一个主键,一个主键可以不只仅有一列。
-数据行
insert into tb1(name,age) value('alex',18);
delete from tb1;
truncate table tb1;
delete from tb1 where id>10
update tb1 set name='root' where id>10
select * from tb1;
select id,name from tb1;
对于自增:
desc 表:查看表的规则
show create table 表 \G:查看怎么创建表的
alter table t1 auto_increment=20;修改自增
MySQL:自增步长
基于会话级别:
show session variables like 'auto_inc%'; 查看全局变量
set session auto_increment_increment=2; # 对当前的客户端
基于全局的级别;
show global variables like 'auto_inc%';查看全局变量
set global auto_increment_increment=2; # 对所有的客户端
sqlServer:自增步长
基于表级别
今日内容:
0.唯一索引
索引的目标:加速查看的作用
单列索引,不能重复
create table t1(
id int....,
num int,
xx int,,
unique uq1 (num,xx) # 联合索引
)
# 1 1 1
2 1 2
ps:
唯一:
约束不能重复(可以为空)
ps: 主键不能重复(不能为空)
1.外键的变种
a. ===> 多对一
b.FKFK() + 唯一
博客园,一个用户仅能注册一个账号
博客表
===> 一对一
c.用户表(百合网)
示例1:
用户表
相亲表
示例2:
用户表
主机表
关系表
===> 多对多
Table: t1
Create Table: CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(10) DEFAULT NULL,
`gender` char(3) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8
Table: t2
Create Table: CREATE TABLE `t2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
Table: t4
Create Table: CREATE TABLE `t4` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) NOT NULL,
`hostid` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uq_user_host` (`userid`,`hostid`),
KEY `fk_host` (`hostid`),
CONSTRAINT `fk_host` FOREIGN KEY (`hostid`) REFERENCES `t2` (`id`),
CONSTRAINT `fk_user` FOREIGN KEY (`userid`) REFERENCES `t1` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8
2.SQL语句的数据行操作补充
增
insert into tb(name,age) values('alex',12),('root',18);
insert into tb(name,age) select name,age from tb1;从另外一个表中导入相应的数据
删
delete from tb;
delete from tb1 where id=1 and name='alex'; 条件语句
改
update tb1 set name='alex',age=19 where id>12 and name='xxx'
查
select * from tb1;查全部,效率低
select id,name from tb1 where id >10 or name = 'xxx'
select id,name as cname from tb1 where id >10 or name = 'xxx'; #别名
select id,name,1 from tb1 where id >10 or name = 'xxx';加各外的列显示
其他
select id,name from tb1 where id !=10
select id,name from tb1 where id in (1,5,12);
select id,name from tb1 where id not (1,5,12);
select id,name from tb1 where id between 1 and 10;(闭区间)
select id,name from tb1 where id in(select id from tb11);
select id,name from tb1 where name like 'a%';以a开头的所有字符,%a%,有a的字符,%a,以a结尾。a_,a开头的下一个任意的两个字符。
select * from tb1 limit 10;查看前10条数据
select * from tb1 limit 4,10;第一个数据是从4开始,取10条
select * from tb1 limit 4 offset 20; 开始到结束
排序:
记忆:abcd
select * from t1 order by id desc;# 从大到小排序
select * from t1 order by id asc; # 从小到大排序
取后10条数据
select * from t1 order by id desc limit 10;
分组:
select min(id),part_id from userinfo5 group by part_id
select count(id),part_id from userinfo5 group by part_id
聚合函数:
count
max
sum
avg
如果对于聚合函数结果进行二次筛选时,必须使用having
select count(id),part_id from userinfo5 group by part_id having count(id)>1
select count(id),part_id from userinfo5 where id>0 group by part_id having count(id)>1 # 在聚合之前可以使用where筛选
连表操作:
select * from userinfo5,department5 where userinfo5.part_id = department5.id
select * from userinfo5 left join department5 on userinfo5.part_id = department5.id
# userinfo5左边全部显示
select * from userinfo5 right join department5 on userinfo5.part_id = department5.id
select * from userinfo5 inner join department5 on userinfo5.part_id = department5.id
# 将出现null时一行隐藏
select count(id) from userinfo5;
Day3:
转储SQL文件
mysqldump -u root db1 > db1.sql -p :备份,数据表结构+数据
mysqldump -u root -d db1 > db1.sql -p :备份,数据表结构
执行文件:
create database db5;
mysqldump -u root -d db5 < db1.sql -p
作业讲解:
select teacher_id,count(cname) from course group by teacher_id;
#合并男女生的个数
select gender,count(sid) from student gourp by gender;(合并相同的)
临时表:
select sid from (select * from score where num >60) as B;
select B.student_id,B.avgerment,student.sname from
(select student_id,avg(number) as avgerment from score group by student_id having avg(number)>60) as B
left join student on B.student_id=student.sid;
select score.student_id,student.sname,count(score.sid),sum(score.number)
from score left join student on score.student_id=student.sid group by score.student_id;
select student.sid,student.sname from student where sid not in
(select student_id from score where corse_id in (select cid from course left join teacher on course.tearch_id=teacher.tid where teacher.tname='波多') group by student_id);
Day4
今日内容:
练习题
pymysql 模块:
pip3 install pymysql -i https://pypi.douban.com/simple
python模块:对数据库进行操作(SQL语句)
上节回顾:
1.MYSQL:文件管理的软件
2.三部分:
-服务端
-SQL语句
-客户端
3.客户端:
-mysql
-navicat
4.授权操作
-用户操作
-授权操作
5.SQL语句
-数据库操作
-create database xx default charset utf8;
-drop database xx;
-数据表
-列
-数字:整数,小数
-字符串
-时间
-二进制
-其他:引擎,字符表,起始值
引擎:支持事务,原子性操作,当两个事物想关联时,一个事物失误,则回到原来的状态
-主键索引
-唯一索引
-外键:约束,节省内存空间(相同的内容,用id来表示)
-一对多
-一对一
-多对多
-数据行
-增
-删
-改
-查
- in not in
-between and
-limit
-group by having
-order by
-like '%a'
-left join xx on
-临时表
-select
id,
name,
1,
(select count(1) from score)
ps:数据放在硬盘上
作业讲解:
select score.student_id,student.sname from score left join student on score.student_id=student.sid
where corse_id=1 or corse_id=2 group by student_id having count(corse_id)>1 ;
查询学过'波多'老师所教的所有课的同学的学号、姓名;
select score.student_id,student.sname from score left join student on score.student_id=student.sid
where score.corse_id in (select cid from course left join teacher on course.tearch_id=teacher.tid where tname='波多')
group by student_id having count(corse_id)=(select count(cid) from course left join teacher on course.tearch_id=teacher.tid where tname='波多');
去重:distinct ,效率不高
select distinct student_id from score where num<60
添加选择的地方,添加case when 条件 then 结果 else 结果 end
select course_id,avg(num),sum(case when num <60 then 0 else 1 end)/sum(1) as jgl from score group by course_id order by avg(num) asc,jgl desc;
SQL三目运算;if(isnull(score.num,0,score.num)
uu' or 1=1 --1 q
-连接、关闭(游标)
-execute() -- SQL注入
-增删改:onn.commit()
-fetchone fetchall
-获取插入数据自增ID
练习:
权限管理
权限表:
1 订单管理
2 用户管理
3 菜单管理
4 权限分配
5 Bug管理
用户表:
用户权限关系表;
python实现:
某个用户登录后,查看自己拥有的所有权限
Day5
1.视图
某个查询语句设置别名,日后方便使用
-创建
create view 视图名称 as SQL
PS:虚拟
-修改
alter view 视图名称 as SQL
-删除
drop view 视图名称
2.触发器
当对某张表做:增删改操作时,可以使用触发器自定义关联行为
insetr into tb(...)
delimiter //
create trigger t1 before insert on student for each row
begin
insert into teacher(tname) values(new.sname);
end //
delimiter ;
new,代指新数据
old,代指老数据
3.函数
内置函数
执行函数 select curdate()
自定义函数
常用的函数;
date_format,
创建一个函数(有返回值):
delimiter \\
create function f1(
i1 int
i2 int)
return int
BEGIN
declare num int default 0;
set num = i1 + i2;
return(num);
end \\
delimiter ;
select f1(1,100)
4.存储过程
保存在MySQL上的一个别名 => 一大块SQL语句
别名()
用于替代程序员写SQL语句
方法一:
MYSQL:存储过程
程序:调用存储过程
方式二:
MySQL:...
程序:SQL语句
方式三:
MYSQL:...
程序:类和对象(SQL语句)
1)没有参数
delimiter //
create procedure p2()
begin
select * from studnet
end //
delimiter ;
2).传参数(in,out,inout)
delimiter //
create procedure p2(
in n1 int,
in n2 int
)
begin
select * from student where sid > n1;
end //
delimiter ;
call p2(12,2)
cursor.callproc('p2',(12,2))
3).参数 out
delimiter //
create procddure p2(
in n1 int,
out n2 int
)
begin
set n2 = 123;
select * from student where sid > n1;
end //
delimiter ;
set @v1=0;
call p2(12,@v1);
select @v1; # 查看数据
pymysql
cursor.callproc('p2',(12,2)
拿结果集:
cursor.callproc('p2',(12,2))
r1 = cursor.fetchall()
print(r1)
cursor.execute('select @p2_0,@p2_1')
r2 = cursor.fetchall()
print(r2)
存储过程的特性:
1.存储过程没有return,只能通过out来伪装取得数据
2.可传参数:in out inout
3.pymysql
为什么有结果集又有out伪装的返回值?
Out 用于标识存储过程的执行结果 0,1,成功与否
5.索引
6.ORM操作-类对象对数据进行操作
delimiter // 修改终止符
7.事务
delimiter //
create procedure p4()
begin
--1.声明如果出现异常则执行{
set status =1
rollback;
}
开始事务
--由秦兵账号减去100
--方少伟账户加90
--张根账号10
commit;
结束
set status = 2
end //
delimiter ;
8.游标
1.声明游标
2.获取A表中数据
my_cursor select id,num from A
3.for row_id,row_num in my_cursor:
#检测循环是否还有数据,如果无数据
# break;
insert into B(num) values(row_id + row_num)
游标的数据性能低
用游标的地方:当对表中的每一行数据要做操作时,可以用游标
-- delimiter //
-- create procedure p1()
-- BEGIN
-- DECLARE row_id int;
-- DECLARE row_num int;
-- DECLARE done int default FALSE;
-- declare temp int;
--
-- declare my_cursor CURSOR for select id,number from A;
-- declare CONTINUE HANDLER for not FOUND set done = TRUE;
--
-- open my_cursor;
-- xxoo:loop
-- FETCH my_cursor into row_id,row_num;
-- if done THEN
-- leave xxoo;
-- end if;
-- set temp = row_id+row_num;
-- insert into B(num) values(temp);
-- end loop xxoo;
-- close my_cursor;
-- end //
-- delimter ;
CALL p1();
9.动态执行sql(防SQL注入)
delimiter //
create procedure p7(
in tp1 varchar(255),
in arg int
)
begin
1.预检测某个东西,SQL语句合法性
2.SQL = 格式化 TPL + ARG
3.执行SQL语句
set @xo = arg;
prepare xxx FROM 'select * from student where sid >?'
execute xxx using @xo;
deallocate prepare xxx;
end //
delimiter ;
回顾:
左右连表:join
上行连表:union(自动去重) /union all(不去重)
作业:
基于角色的权限管理,懂得需求分析
1.用户信息
id username pwd role_id
2.权限
3.角色表
4.角色权限管理
使用函数,会让SQL的性能低
Day6
内容回顾:
1.数据库是什么
2.mysql安装
3.用户授权
4.
数据库操作
数据表
数据类型
是否可以为空
自增
主键
外键
-一对多
-多对多
-一对一
唯一索引
数据行
增
删
改
查
排序:order by desc/asc
分组:group by
条件:where
连表:
left join
right join
inner join
临时表:
通配符
分页:Limit
组合:union
视图(虚拟的,临时的)
触发器(增加前,增加后,对于每一行数据来说的)
函数(select xx(f))
存储过程
-游标
-事务
--结果集+‘返回值’
pymysql
-连接 connect(..)
-操作(游标),可以改输出格式,默认是元祖
-增删改 -> commit
-查 ->fetchall ,fetchone
-SQL注入
-调用存储过程
-callproc('p1',参数)
-select @_存储过程名称_0
-关闭游标
-关闭连接
-存储过程调用方式
-commit
-select fetchone
-SQL注入(注释--)
今日内容:
1.索引
作用:
-约束
-加速查找
索引:
-普通索引:加速查找
-主键索引:加速查找+不能为空+不能重复
-唯一索引:加速查找+不能重复
-联合索引(联合唯一)
-联合主键索引
-联合唯一索引
-联合普通索引
加速查找:
create index ix_name on userinfo<email>
无索引:从前到后依次查找
索引:
创建额外文件(某种格式存储)
假设:
id name email
...
...
索引:
id 创建额外文件(某种格式存储)
name 创建额外文件(某种格式存储)
email 创建额外文件(某种格式存储)create index ix_name on userinfo<email>,drop index ix_name on userinfo<email>
name email 创建额外文件(某种格式存储)
索引种类:
hash索引:索引表(因为hash表存的数据不是按顺序的)
单值快
查范围很慢
btree索引
二叉树(比如查多少次才能查到)
建立索引:
-a.额外的文件保存特殊的数据结构
-b.查询快:插入更新删除慢
-c.命中索引
普通索引:
-create index 索引名称 on 表名(列名)
-drop index 索引名称 on 表名
唯一索引:
-create unique index 索引名称 on 表名(列名)
-drop unique index 索引名称 on 表名
联合索引:
-最左前缀匹配
-create unique index 索引名称 on 表名(列名1,列名2)
-drop unique index 索引名称 on 表名
不是真实的索引:
覆盖索引:
-在索引文件中直接获取数据
索引合并:
-把多个单列索引合并使用
组合索引效率 > 索引合并
2.频繁查找的列创建索引
-创建索引
-名字索引
这样才真正的快
3.时间
执行计划:让mysql预估计时间
type:ALL(全表扫描)
4.DBA工作
优化SQL
慢日志
-执行时间>10
-未命中索引
-日志文件路径
配置:
-内存
show variables like '%query%';
set global 变量名 = 值
-配置文件
mysqld --defaults-file=配置文件路径
配置文件的内容,会在首次启动mysqld时,加载在本地的配置文件里面
注意:修改配置文件之后,需要重启服务
5.分页
分的数字越大,就越慢
a.不让看
b.索引表中扫 select * from userinfo3 where id in (select id from userinfo3 limit 200000,10)
c.方案:记录当前页最大或最小ID
1.页面只有上一页,下一页
max_id
min_id
下一页:
select * from userinfo3 where id>max_id limit 10;
上一页:
select * from userinfo3 where id <min_id order by id limit 10;
2.上一页192 193 196 197 198 199 下一页
select * from userinfo3 where id in(
select id from (select id from userinfo3 where id > max_id limit 30) as N order by N.id desc limit 10)
ID不连续,所以无法直接使用ID范围进行查找(between 初始数据 and 终止数据)
Day7
内容回顾:
1.无面向对象,完全可以编程
def func(arg):
return arg + 1
面向对象
1.当一类函数共用同样参数时候,可以转变成类过程-分类
2.面向对象:数据和逻辑组合在一起了
函数编程:数据和逻辑分离的
3.模板“约束”
-一类事物共同具有:属性和行为
提取共性
分类
class Foo:
def __call__(self):
pass
obj1() 对象加括号,直接调用call方法
1.ORM框架:SQLALchemy
-作用:
1.提供简单的规则
2.自动转换成SQL语句
-DB first:手动创建数据库以及表->ORM框架 -> 自动生成类
-code first:手动数据库,手动创建表->ORM框架 -> 以及表
a.功能
-创建数据库表
-连接数据库(非SQLAlchemy,pymyql,mysqldb,SQLserver,Oracle....)
-类转换SQL语句
类 -> 表
对象 -> 行
先查后删
select * from b where id in ()
select * from (select * from tb) as b
- q1 = session.query(usertype).filter(usertpye.id > 0).subquery()
- result = session.query(ql).all()
select id,(select * from users) from usertpye; # 如果没有as_scalar()的话,会直接形成一个笛卡儿积
result = session.query(usertpye.id,session.query(user).filter(user.id==usertype.id).as_scalar()).all
relationship
1.正向操作,写在有foreignkey的类里面
2.反向操作
前端:
4周~5周
-2周前端
-2周Django基础
编程:
使用(展示)数据 存储数据 处理数据
前端:
1.前端是做什么的?
2.我们为什么要学前端?
3.前端都有那些内容?
1.HTML,2
2.CSS,2
3.javascript,2
4.jquery 和 bootstrap ,3
web 开发本质:
1.浏览器输入网址回车都发生了什么?
1.浏览器给服务器发送一个消息
2.服务器接收到消息
3.服务器返回消息
4.浏览器展示页面
客户端和服务端 消息的格式是约定好的
HTTP协议:浏览器和服务器之间约定好的消息格式 ==>'PUT|XXX.AVI|1024'
WEB本质:
服务端
浏览器
文件
HTML --> 学标签,没有逻辑
<标签名> -- >标记语言(HTML,XML)
标签分类:
双标签
单标签
<h1></h1>
<img>
<a></a>
HTML文件的结构:
1.文档声明
2.html标签
-head标签
head内常用标签
body内常用标签
-body标签(用户在浏览器能看到的内容)
2.注释
<!--注释内容-->
3.常用的标签
h1~h6
img
a
4.<div><span> 最大的特点就是没有特点
<div> 没有换行
<span>换行
标签分类:
块级标签 h1~h6 div p hr
默认占浏览器宽度
内联标签(行内标签) a img u s i b span
根据内容决定长度
不能设置长和宽
5.语义化的HTML
h1*4>a.c1[id=a$]{a标签$}
emmt,写前端的补全的格式
6.标签的嵌套规则
1.行内标签不能嵌套块级标签
2.P标签不能嵌套块级标签
作业:
1.整理博客
2.预习
2.自己开发web框架
-socket
-http协议
-HTML知识
-数据库(pymysql,sqlalchemy)
Day2
1.form表单相关内容
前后端有数据交互的时候用form表单
form表单提交数据的几个注意事项:
1.所有获取用户输入的标签都必须放在form表单里面
2.action控制往哪提交数据
3.input\select\textarea 都需要有name属性
4.提交按钮<input type="submit">
小总结:
input系列
text
value 设置默认值
placeholder 设置占位内容
password
radio 单选框
checkbox 多选框
date 日期
datetime 时间
file 文件
button 普通按钮,多用JS给它绑定事件
reset 重置
submit 条件
textarea 大段文本
select 下拉菜单
option
optgroup 分组的下拉菜单
什么时候使用<input tpye="hidden">
<label for="r1">男</label>
<input id="r1" name="gender" type="radio" value="1">
<label>男
<input name="gender" type="radio" value="1">
</label>
2.CSS
HTML 骨架
标签1 样式xxx1
标签2 样式xxx2
标签3 样式xxx3
1.重复的样式
2.文档内容和样式的解耦
-->CSS 层叠 样式 表
-->CSS如何引入?
1.直接写在标签里面 style="样式1;样式2;"
2.在head中通过style标签定义
3.把样式单独写在CSS文件中,然后在html文件中通过link标签导入
-->CSS语法
选择器 {样式1;样式2}
基本选择器:
1.元素选择器
2.ID选择器
3.类选择器
通用选择器:
1.*
当样式有重复的时候,推荐分行写选择器,但是一定要加逗号
--> 样式文件优先级
1.选择器都一样的情况下,谁靠近标签谁就生效
2.内联样式(直接在标签里面写style)优先级最高
Day3
1.内容回顾:
1.昨日内容
1.form表单(一般method="post")
1.input 系列
tpye
1.text
2.password
3.radio
4.checkbox
5.date (datetime)
6.submit
7.button
8.reset
9.hidden
10.file (method="post" enctype="multipart/form-data")
2.select
select>option(分组的下拉框,select>optgroup>option)
3.textarea
2.form表单提交 三要素:
1.input\select\textarea 要有一个name属性
2.提交按钮必须要是type="submit"
3.form不是from;获取用户输入的标签都要放到form标签里面(仅限于form提交数据)
3.CSS选择器
1.基本选择器
1.标签选择器
2.id选择器
3.类选择器(clss)
2.通用选择器(*)
3.组合选择器
1.后代选择器(空格)
2.儿子选择器(>)
3.毗邻选择器(div+p)
4.弟弟选择器(~)
4.属性选择器
1.[title,自定义]
5.分组和嵌套
1.分组(用逗号分隔的多个选择器条件)
2.嵌套(选择器都可以组合起来使用)
6.选择器的优先级
1.越靠近标签的优先级越高(就近原则)
2.权重的计算
1.内联样式1000
2.ID选择器100
3.类选择器10
4.元素选择器1
div#d1(101)/div.c1(11) 没有空格,就是and的意思
2.之前内容复习
1.python语法基础
2.数据类型和内置方法
3.函数
1.参数
2.装饰器
3.迭代器和生成器
4.匿名函数
5.递归
6.内置函数
7.三元运算和列表推导式
4.文件操作
5.面向对象
6.常用的模块和包
7.网络编程和并发编程(优先级低)
8.数据库(建库\建表\基本查询)
建立自己的自信
3.CSS属性
1.padding:内容区和边框之间的距离(内填充/内边距)
2.margin:边框之外的距离(多用来调整 标签和标签之间的距离)
3.浮动:div配合float来做页面的布局
定位:
1.默认的static
2.相对定位(相对于原来的位置来说)
3.绝对定位(相对于最近一个被定位过的祖宗标签)
4.固定在某个位置(返回顶部)
left right top buttom
DAY4
1.内容回顾
1.伪类和伪元素
1.伪类
1.:link
2.:visited
3.:hover(重要)
4.:active
5.:foucus(input标签获取光标焦点)
2.伪元素
1.:first_letter
2.:before(重要 在内部前面添加)
3.:after(重要 在内部后面添加)
2.CSS属性
1.字体
1.font-family
2.font-size
3.font-weight
2.文本属性
1.text-align 对齐
2.text-decoration 装饰(去除a标签的下划线(text-decoration:none))
3.text-indent 首行缩进
3.背景属性
1.background-color 背景颜色
2.background-image 背景图片 url() no-repeat 50% 50%
4.color
1.red(直接写名字)
2.#FF0000
3.rgb(255,0,0) --> rgba(255,0,0,0.5)
5.边框属性 border
1.border-width(边框宽度)
2.border-style(边框样式)
3.border-color(边框颜色)
简写:
border:1px solid red;
6.CSS盒子模型
1.content(内容)
2.padding (内填充) 调整内容和边框之间距离时使用这个属性
3.border(边框)
4.margin(外边框) 多用于调整调整标签之间的距离(注意两个挨着的标签的margin,取大)
注意:要习惯看浏览器console窗口那个盒子模型
7.display(标签的展示形式)
1.inline
2.block 菜单里面的a标签可以设置成block
3.inline-block
4.none(不让标签显示,不占位)
8.float(浮动)
1.多用于实现布局效果
1.顶部的导航条
2.页面左右分栏(博客页面:左边20%,右边80%)
2.float
1.任何标签都可以浮动,浮动之后都会变成块级 a标签float之后就可以设置高和宽的
3.float取值
1.left
2.right
3.none
9.clear 清除浮动-->清除浮动的副作用(内容飞出,父标签撑不起来)
1.结合伪元素来实现
.clearfix:after {
content:'',
display:'block'
clear:both;
}
clear取值:
1.left
2.right
3.both
10.overflow
1.标签的内容放不下(溢出)
2.取值:
1.hidden -- > 隐藏
2.scroll --> 出现滚动条
3.auto
4.scroll-x
5.scroll-y
例子:
圆形头像的例子
1.overflow:hidden
2.border-randius:50% (圆角)
11.定位 position
1.static(默认)
2.relative(相对定位--> 相当于原来的位置)
3.absolute(绝对定位 --> 相当对于定位过的前辈标签)
4.fixed(固定 -- > 返回顶部按钮示例)
脱离文档流:
float
absolute
fixed
12.opacity(不透明度)
1.取值0~1
2.和rgba()的区别:
1.opacity改变元素\子元素的透明度效果
2.rgba()只改变背景颜色的透明度效果
13.z-index
1.数值越大,越靠近你
2.只能作用于定位过的元素
DAY5:
1.内容回顾
1.HTML
1.标签
1.标签分类
1.块级标签
2.内联标签
2.常用标签
1.a table p h1~h6 div span ul ol dl
2.form表单系列(不是from)
1.input
1.text
2.password
3.date datetime
4.email
5.radio
6.checkbox
7.button/submit/reset
8.file(上次文件,form标签写一个特殊属性:enctype)
和input标签绑定使用的label
2.select(下拉框)
1.加一个multiple属性变成多选
2.分组的select
<select>
<optgroup lable="分组名">
<option>
3.textarea(大段文本)
2.CSS
1.选择性
1.基本选择器
元素 ID 类 通用
2.组合选择器
后代(空格) 儿子 毗邻 弟弟
3.属性(inpuut)
4.分组和嵌套
5.伪类和伪元素
选择器的优先级
1.选择器相同:就近原则(越靠近标签优先级越高)
2.权重的计算(内联1000>ID100>类10>元素1)
2.CSS属性
1.字体属性
2.文本属性
3.边框
4.背景
5.盒子模型
6.display(显示)
7.overflow(溢出)
8.float(浮动)
9.position(定位) -->相对定位/绝对定位/固定定位
10.clear(清除浮动)
11.z-index(垂直屏幕,数值越大越靠近用户)(弹出的模太框示例)
12.opacity(透明度)
13.color
2.今日内容:
1.javascript
1.基础语法
1.注释
2.语句必须以分号结束
3.变量声明的关键字:var 变量名=‘值’
JS属于动态类型(同一变量可以赋值不同的数据类型)
4.变量
变量命名规则 JS中$也可以用来命名
推荐使用驼峰命名规则
2.数据类型
1.数字 number
1.NaN
2.字符串string
3.布尔值 boolean
4.数组 array
5.null
6.undefined
3.函数
4.面向对象
注释:
//单行注释
/*
*多行注释
*/
null == undefined 返回的是true
== 弱等于
=== 强等于 既判断值又判断类型
c = a if a>b else b
c = a > b ? a:b
Day6
复习:
1.while循环
var i = 5
while (i>0) {
console.log(i);
i--;
}
2.运算符
算数运算符
比较运算符
逻辑运算符
赋值运算符
函数:
1.作用域:
调用函数的时候要找会函数声明的地方
首先在函数内部找->内部找不到就往外找->找不到就变成undefined
2.词法分析
1.分析(分析函数内部变量定义)
定义
声明
2.执行
赋值
函数调用
3.点,是直接取对象中存在的属性值。[] ,多用于属性名是保存在变量中的情况
4.自定义对象的第二种方式:通过new关键字创建对象
内置方法:
1.date对象 -->Python中的内置模块
document.body.contentEditable=True;
正则表达式;
1.正则表达式中间一定不能有空格。
2.test()不传值相当于传了一个undefined进去了,然后test()就把这个undefined当成"undefined"来判断
3.g 表示全局 i 忽略大小写
4.当正则表达式使用了全局模式(g)的时候,并且你还让它去检测一个字符串,此时会引出一个lastIndex会记住上一次匹配成功的位置
并把下一次要开始校验的位置记住
Day7
1.内容回顾
parseInt("111")
parseFloat("11.11") 当转的时字符时,则显示的时NaN
函数
函数的定义:
一般函数定义:
function foo(a,b){函数的代码块;return 返回值}
匿名函数:
var bar = function(){...}
立即执行函数:
(function(a,b){...})(实参1,实参2)
函数的参数:
不严谨
arguments:函数内部可以通过arguments拿到所有的参数
作用域
函数内部可以调用函数外部的变量
函数外部无法访问函数内部的变量
词法分析
函数调用的一瞬间要做两部:
1.分析(AO对象)
1.先分析有没有参数;
2.看看有没有局部变量;
3.看看有没有声明函数;
2.执行
取值都是从AO对象去找
注意:函数没有指定的返回值,返回的就是undefined
自定义对象
1.var p1= {name:"xiaolin",age:38}
2.var p2 = new object();
p2.name = "xiaoqiang";
p2.age = 38;
遍历自定义对象:
for (var i in p1) {
console.log(i) ; //键
console.log(p1[i]);}
内置对象和方法
1.Date
1.生成对象
var d1 = new Date()
var d2 = new Date("2019-01-09")
2.方法:
d1.toLocalString()
d1.toUTString()
d1.getFullYear()
d1.getMonth()
d1.getDay()
2.json
1.字符串转JSON对象
var jsonobj = JSON.parse('{"name":"xiaoqiong","age":18}')
2.JSON对象转成字符串
var s = JSON.stringify(jsonobj)
3.Math
4.RegExp
1.定义正则两种方式
1.var regobj1 = new RegExp("^[1-9$");
2.var regobj2 = /"^[1-9$"/
2.常用方法:
regobj1.test("将要被检验的字符串")
3.正则的匹配模式
1.g --> 全局
"alexdashabi".replace(/a/g,"呵呵")
2.i -- > 不区分大小写
"alexdashabi".replace(/a/i,"呵呵")
4.几个坑
1.正则表达式之间不能加空格
2..test()不传值相当于 .test(undefined) --> .test("undefined")
3.全局匹配模式注意事项,当从头到尾检验一个字符串时不要加g
var reobj = /alex/g;
reobj.test("Alex") -- > lastIndex=4,所以下一个匹配时,是从第5个字符开始
2.今日内容
1.BOM
1.location
1.location.href --> 获取到当前的URL
2.location.href="httpF://www,baidu.com" --> 跳转到指定网页
3.location.reload --> 刷新
2.setTimeout 和clearTimeout
多少毫秒之后做什么事儿
3.setInterval 和clearInterval
2.DOM
1.什么是DOM树
2.DOM都有那些内容
3.JS操作DOM
1.找标签
1.基本查找
1.根据ID找标签(有且只能找到一个)
document.getElementByID("ID值")
2.根据class名字找(找到的可以是多个)
document.getElementsByClassName("class值")
3.根据标签名找(找到的可以是多个)
document.getElementsByTagName(”标签名“)
2.间接查找
1.找父标签
2.找子标签
3.第一个子标签
4.最后一个子标签
5.前一个兄弟标签
6.后一个兄弟标签
2.创建标签
createElement("标签名")
3.添加标签
1.在内部的最后添加
appendChild("标签名")
2.在内部的某个标签的前面插入
insertBefore(新标签,插入的位置的标签)
3.1 删除标签
1.从父标签里面删除指定的标签
父标签.removeChild(指定的标签)
3.2 替换
1.在父标签里面用新创建的标签替换指定标签
父标签.replaceChild(新创建的标签,指定的标签)
4.属性(内置属性)
.属性名="属性值"
自定义的属性
.setAttribute("s9","hao")
.getAttribute("s9")
.removeAttribute("s9")
5.设置文本操作
1.设置文本的内容
.innerText=""
2.设置标签内容
.innerHTML="<p>我是p标签</p>"
3.获取值的区别
1..innerText 获取标签的文本
2..innerHTML 获取标签里面的标签
5.1 获取值(input\select\textarea)
input标签.value()
select标签.value()
textarea标签.value()
6.样式操作
1.通过class名去改变样式
1.获取标签所有样式类
1..className -->得到的是字符串
2..classList --> 得到的是数组
2.使用classList操作样式
1..classList.contains(“样式类”) -- > 判断包不包含指定的样式类
2..classList.add(“样式类”) -->添加指定的样式类
3..classList.remove("样式类") --> 删除指定的样式类
4..classList.toggle("样式类") --> 有就删除没有就添加
3.通过.style直接修改CSS属性
1.CSS属性中不带中横线的
.style.color=red;
7.事件
0.注意:涉及到DOM操作的代码,需要放在body的最下面
1.用户可以在浏览器上点标签
2.标签会触发一个点击的事件
3.事件需要有函数来处理
4.常用事件
1.onclick;
2.ondbclick;
3.onfocus;
4.onblur;
5.onchange;
5.绑定事件的方式
1.在标签里直接写属性(onclick=foo())
2.通过JS给标签绑定事件
6.this表示当前事件的标签
Day8
1.jquery
1.为什么要学jQuery?
做同样的事情 jQuery写起来及其简练 (write less,do more)
2.jQuery是什么?
jQuery相当于python的第三方模块
第三方模块其实就是别人写好(封装)的一些代码,我们拿过来用(按照别人定好的规则)
原生的JS DOM操作是基础
3.jQuery学习的内容
1.改变标签
2.改变标签的属性
3.改变标签的样式
4.事件
学习的内容(先导入在引用)
0.HTML对象和jQuery对象的区别
1.jquery对象转换成DOM对象,用索引取出具体的标签
2.DOM对象转换成jQuery对象,$(DOM对象)
注意:
jQuery对象存入变量时,变量名需要加$
1.标签
Day9
1.内容回顾
1.jquery
1.选择器 $("")
1.基本选择器
1.ID --> $("#d1")
2.标签名 --> $("p")
3.class名 --> $(.c1)
4.通用的 --> $("*")
5.组合 -> (".c1,div,a")
2.层级选择器
1.子子孙孙 --> $("x y")
2.儿子选择器 --> $("x>y")
3.弟弟选择器 --> $("x~y")
4.毗邻选择器 --> $("laber+input")
2.筛选器
1.基本筛选器
1.:first
2.:last
3.:eq() -->从0开始
4.:even --> 偶数
5.:odd -- >奇数
6.:gt
7.:lt
8.:not
9.:has
2.属性选择器
1.$("[title]")
2.$(["type='text']")
3.$(["type!='text']")
3.表单选择器
1.$("input[type='checkbox']") -->$(":checkbox")
4.表单对象
1.$(":disabled") --> 找到不可用的标签
5.筛选器方法(应用场景和上面的基本筛选器的不同)
1.$("div").first()
2....
6.常用的方法
1..next() -->找到挨着我的下一个同级标签
2..nextAll() --> 下边同级的所有
3..nextUntil() --> 往下找,直到找到终止条件为止
4..prev()
5..prevAll()
6..prevUntil()
7..siblings() -->找所有的兄弟(包括前面和后面的)
8..children()
9..parent()
10..parents()
11..parentsUntil()
12..find(各种条件都可以写)
3.样式操作
1.操作class类
1..addClass()
2..removeClass()
3..hasClass()
4..toggleClass()
2.今日面试题
1.问:字符串格式化:%和format 有什么区别?
python新版本推荐使用format。Python2.6新加入了format特性。在python3.6加入了f-string
3.今日内容
1.修改样式
1.操作class类
自定义模态框弹出和隐藏
2.直接修改样式
1.原生的DOM .style.color="green"
2.$("div").css("color","green")
3.修改多个样式时,传入键值对
3.位置
1.height(),.width() 内容区的高和宽
2.innerHeight(),.innerWidth() 内容区加padding
3.outerHeight(),outerWidth() 内容区+padding+border
2.文档操作
3.属性操作
attr
Day10
1.内容回顾
1.jQuery
2.Bootstrap框架
1.Bootstrap
1.样式类
1.栅格系统
0.包含在container里面
1.每一行(row)均分12列
2.每个标签可以自定义占的列数(col-xx-**)
Day11
1.导入Bootstrap.css
2.还要bootstrap.js,并且还要引入jquery
3.栅格系统
1.container,row必须包含在container中
2.每一行被均分成12列,col-xx-**(xx[lg,md,sm,xs]|**[1~12])
3.只有列能作为行的直接子元素
今日内容:
4.作业:
1.后台管理页面自己写出来(第一个Django项目要用)
2.Toastr自己尝试着写几个例子,有个印象
3.整理今天的组件
4.复习装饰器
DjANGO框架
内容回顾:
1.安装MySQL
2.创建用户+授权
3.
连接
--数据库
终端创建数据库(字符编码)
--数据表
终端
ORM
pymyql
--数据行
增
删
改
查
关闭
简述ORM原理:把类的对象和方法转换成SQL语句再根据接口调用相对性的第三方工具,比如pymysql,MS SQL server
弄清楚什么是code first(*) db first(*)
今日内容概要:
1.自己开发web框架
-socket
-http协议
-HTML知识
-数据库(pymysql,SQLALchemy)
HTTP:无状态,短连接
TCP:不断开
WEB应用(网站)
浏览器(socket客户端)
2.www.cnblogs.com
sk.socket()
sk.connect()
sk.send('我想要XX')
5.收到
6.连接断开
博客园(socket服务端)
1.监听IP和端口
3.收到'我想要xx'
4.响应:‘好’
用户断开
总结:
1.HTTP,无状态,短连接
2.浏览器是sockt客户端
3.网站是socket服务端
4.自己写网站
a.socket服务端
b.根据url不同返回不同的内容
路由系统:
URL -> 函数
c.字符串返回给用户
模板引擎渲染:
HTML充当模板(特殊字符)
自己创造任意数据
返回字符串
5.web框架:
框架种类:
- a,b,c --> Tornado
- [第三方a],b,c -- wsgiref -> Django
- [第三方a],b,[第三方c] --> flask,bottle,
分类:
-Django框架(web....)
-其他
Django框架(主要实现业务)
pip install django
命令:
django-admin startproject mysite
cd mysite
python manage.py runserver 127.0.0.1:8080
Django程序目录:
mysite
-settings.py # Django配置文件
-url.py # 路由系统:url->函数
-wsgi.py # 用于定义Django用socket,wsgiref,uwsgi
manage.py # 对当前Django程序所有操作可以基于python manage.py XXX
模板路径的配置和静态文件路径的配置
1.创建project
2.配置:
-模板路径
template目录 用来显示html文件(render)
-静态文件路径
static 用来导入css,js,等文件的
3.额外配置
在setting文件中注释掉这个字符串
'django.middleware.csrf.CsrfViewMiddleware'
4.request.GET 获取的是网址上面发过来的数据
5.URL对应关系
/login/ login/
def login(request):
request.method
request.POST -> 请求体
request.GET -> 请求头的url中
return HttpResponse(..)
return render(request,'login.html',{...}
return redirect('网址')
GET请求 -> request.GET
POST请求 -> request.GET和request.POST
for 循环和html结构起来
6.模板引擎中的特殊标记
作业:
Django + pymysql 实现
-用户登陆
-查看用户列表
Day65
内容回顾:
1.web框架本质
-本质socket
-Http协议
-头
-体
-字符串
2.Django
-安装
-Django-admin startproject mysite
-wsgi 协议
-1.配置
-模板路径
-静态文件
-CSRF注释
-2.urls.py
URL -> 函数
-3.函数
def index(request):
request.method
request.GET
request.POST
return HttpResponse(..)
return reder(request,'模板路径',{})
return redirect('URL')
-模板渲染
学生管理:
表:
班级
学生
老师
单表操作:
-增
-删
-改
-查
一对多操作:
-增
-删
-改
-查
多对多操作:
-增
-删
-改
-查
今日作业:
-老师管理
-对话框:添加、删除 [可选]
html注释的符号就是<!-- 注释内容 -->;为Jinja2的时候,注释符号就是{# 注释内容 #}
Day66
1.学生管理,实现一对多的关系(一个班级对应多个学生)
ps:在view中添加一个对读取到的数据是否为空进行判断
2.模态对话框
FORM表单提交,页面会刷新
对话框,不能用form表单来提交
3.Ajax
引入jquery
$.ajax({
url:'要提交的地址',
type:'POST',//GET或者POST,提交方式
data:{'k1':'v1','k2':'v2'},//提交的数据
success:function(data){
//当前服务端处理完毕后,自动执行的回调函数
//data返回的数据
}
})
其他:
1.模板语言if条件语句
2.form表单提交,页面会刷新
3.Ajax提交页面不刷新
4.js实现页面跳转:
location.href = '要跳转的地址'
5.模态对话框(Ajax)
-少量的对话框 比如登陆
-数据少
新URL方式
-操作多
-对于大量的数据以及操作,比如博客
Day67
内容回顾:
1.web框架本质
浏览器(socket客户端)
2.发送ip和端口 http://www.baidu.com:8080/index/
GET:
请求头
http1.1 /index?p=123
...
请求体(无内容)
POST:
请求头
http1.1 /index?p=123
...
请求头
...
4.接收响应
普通响应 :页面直接显示
重定向响应:再一起一次HTTP请求
服务器(socket服务端)
1.启动并监听IP和端口,等待用户连接
3.接收请求进行处理,并返回
普通返回:
响应头:
Bdpagetype: 2
Bdqid: 0xd04146d30009b116
Cache-Control: private
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
Date: Mon, 28 Jan 2019 04:13:17 GMT
Expires: Mon, 28 Jan 2019 04:13:17 GMT
Server: BWS/1.1
Set-Cookie: BDSVRTM=206; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=26522_1433_25810_21118_28329_26350_28415_22072; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
Transfer-Encoding: chunked
X-Ua-Compatible: IE=Edge,chrome=1
响应体:
就是页面返回的显示
<html>
...
</html>
重定向返回:没有响应体
响应头:
LOCATION:'http://www.baidu.com',客户端浏览器再发一次请求,自己去取
2.DjangoWeb框架
a.创建project
Django-admin startproject mysite
b.配置
模板
静态文件
crsf
c.路由关系
url->函数
d.视图函数
def index(request):
request.method
request.post
request.GET
return redirect('URL')
return render(request,'模板路径',{})
1.获取模板+数据,渲染
2.HttpResponse(...)
return HttpResponse('字符串')
e.模板渲染
{{k1}}
{{k2.0}}
{% for i in result %}
{{i}}
{% endfor%}
{% if 1>2 %}
{%endif%}
今日内容:
1.对话框
单表
添加
编辑
删除
ps:
a.js阻止默认事件的发生
b.location.reload()
c.HttpResponse(json.dumps)
d.JSON.parse()
一对多
fixed:相对于窗口来说的
2.多对多
多对多添加
3.Bootstrap
4.fontawesome
Day68
上节回顾:
1.HTTP请求生命周期
请求头-> 提取URL -> 路由关系匹配 -> 函数 (模板+数据渲染) -> 返回用户(响应头+响应体)
2.def index(request):
request.POST.getlist
request.GET.get
request.method
return render()
return HttpResponse()
return redirect()
3.for
if
{{}}
索引.
4.模板渲染是在后台执行的,浏览器拿到的字符串一定是渲染过后的
5.
js序列化
阻止默认事件:
<a onclick='return func();'></a>
<a id></a>
$.ajax({
url:"",
type:'',
data:{},
dataTypye:'JSON',//把JSON的字符串转换成script的对象
success:function(arg) {
}
})
今日内容:
1.学生管理多对多
-新URL方式
-增加
-编辑
-对话框
-增加
-编辑 js判断有不有,就用indexof(222),有则就是索引,没有就返回-1
-遗留:对话框左右移动
2.插件
-bootstrap
-fontawesome
3.用户登录
作业:
后台管理
-用户登录
-学员管理
-单表
-一对多
-多对多
必须完成:
1.表格
2.后台管理布局
ajax:traditional:true
无索引:从前到后依次查找
Day69
1.bootstrap
一个包含CSS和js的一个代码库
-样式
-响应式
@media (max-width:px) {
...
}
-导航条
-栅格
2.完善学员管理系统
-后台管理布局
-Django母版:
母版:存放所有页面公用
子版:继承母版
hover:只能编辑本身和子元素
3.Cookie(响应头)
a.保存在浏览器端的“键值对”
b.服务端可以向用户浏览器端写cookie
c.客户端每次请求时,会携带cookie过去
应用:
a.用户登录
b.投票
set_cookie(self, key, value='',
max_age=None,
expires=None,
path='/',
domain=None,
secure=False, #HTTPS
httponly=False, #只能自HTTP请求中传入,js代码无法获取到
samesite=None)
cookie签名:
obj.set_signed_cokie('ticket','123123',salt='jjjj')
自定制签名
装饰器
Day70
上节回顾:
1.母版
2.Cookie
在浏览器上保存的键值对
def index(request): # 请求头
request.COOKIES
request.get_signed_cookie('k1',salt='fff')
def response(request): # 响应头
obj = HttpResponse(...)
obj = render(...)
obj = redirect(...)
obj.set_cookie(k1,v1,max_age)
obj.set_signed_cokie(k1,v1,max_age,salt='fff')
3.Bootstrap响应式布局
-css
-js
4.后台布局
1.position:absolute
2.
.c1.hover .c2{}
project
-app01 自己创建的目录
-views.py
-SQLHelper 封装SQL操作
Django:
-路由
-视图
-模板
-ORM(类-表;对象-行;pymysql连接数据库)
Tornado:
-路由
-视图
-模板
-自由:pymysql;sqlAchemy
Flask:
-路由
-视图
-模板(第三方的组件)
-自由:pymysql;SQLAchemy
非主流操作:
1.创建app
2.数据库操作
创建django项目:diango-admin startproject mysite
创建多个app:python manage.py startapp app02
project
-app01
- admin Django自带后台管理相关配置
-modal 写类,根据类创建数据库表
-test 单元测试
-views 业务处理 不一定是一个py文件,可以是个文件夹,里面分类了多个业务处理的相关代码
1.路由系统
URL - > 函数
a. /login/ -> def login(request) 静态路由
b. /login/(\w+)/ -> def login(request,a1) 权重加大SEO
c. /login/(?P<a1>\d+)/ -> def login(request,a1) 按值与按位传参不能混合用
ps:
终止符:
^eidt$
伪静态:
url(r'^edit/(\w+).html$,views.edit)
d.路由分发(include)
第一级:urls.py
re_path('^app01/',include('app01.urls')),
第二级:app01.urls.py
re_path('^index.html$',views.index),
e. /add-user/(\d+)/ -> def add_user(request,a1) name=n1
根据名称可以反向生成URL
1.在python代码中
from django.urls import reverse
v = reverse('n1',kwargs={'a1':1111})
print(v)
2.在html的模板中使用反向
url(r'^login/',views.login,name='m1')
{% url "m1" %}
3.ORM操作
HTTP请求:
URL -> 视图(模板+数据)
步骤:
1.创建数据库
2.修改默认的数据库参数
3.在init中修改
4.
from django.db import models
class UserInfo(models.Model): # 创建一个表
nid = models.BigAutoField(primary_key=True)
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
5.注册app
6.创建数据表(在models里面写类)
命令:
python manage.py makemigrations
python manage.py migrate
7.创建表
from django.db import models
class UserGroup(models.Model):
# 部门
tittle = models.CharField(max_length=32)
class UserInfo(models.Model): # 创建一个表
# 员工
nid = models.BigAutoField(primary_key=True)
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
# age = models.IntegerField(null=True)
age = models.IntegerField(default=1) # 外键
# ug_id
ug = models.ForeignKey('UserGroup',null=True)
ORM操作表:
创建表
修改表
删除表
操作数据行:
增删改查
django中的ORM利用pymysql第三方工具连接数据库
默认的数据库是:
sqlite3
默认:
mysql -> MYSQLDB(修改django默认连接mysql方式)
作业:
学生管理(sql换成ORM)
新URL方式:
1.班级增删改查
- /edit-class/?nid=1
- /edit-class/1.html
2.学生管理(FK连表,正向操作和反向操作)
PS:神奇的双下滑线
Day71
上节回顾:
1.路由系统
-静态
-动态
-别名
-无别名
-别名
-根据别名反生成URL
-路由分发
PS:
^$
伪静态:.html
2.ORM操作
- MYSQL -> settings.databases
- pymyql.install_as_mysqldb()
-类
class Foo(models.Model)
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
Foo.object.create(name='ff')
result = Foo.object.all()
QuerySet[Foo(),Foo()]
result = Foo.object.filter(id=1).first() 拿到的是一个对象
result = Foo,object.filter(name = 'alex')
QuerySet[obj,]
QuerySet[obj,obj,obj]
Foo.object.update()
Foo.object.delete()
3.模板语言
-索引
-母版
4.COOKIE
保存在用户浏览器端的键值对
-
今日内容:
1.CBV & FBV
CBV以类的方式类执行
(ajax)
get 查
post 创建
put 更新
delete 删除
(form表单)
post
get
dispath(通过get_attr来反射对应的函数)
4.ORM
多表操作
多个获取,用.
ut是FK字段 - 正向操作
表名小写_set.all() - 方向操作
获取数据的跨表操作
2.Django ORM
3.分页
分批获取数据
models.UserInfo.object.all()[0:10]
-Django自带
-自定义分页组件
Day72
上节回顾:
1.id__gt=6 大于
其他:
all()
filter(id=1,id=2)
all().first()
all().count()
all().update()
all().delete()
all()[1:19]
跨表:
正向:
xxxx.filter('ut__title'='超级用户').values('id','name','ut__title')
反向:
xxxx.filter('表名称__title'='超级用户').values('id','name','表名称__title')
今日任务:
1.Django ORM操作
- 增删改查
- 其他:
- 排序
user_list = models.UserInfo.objects.all().order_by('-id','name')
-分组
annotate
-F,更新时用于获取原来的值
-Q,用于构造复杂的查询条件
-extra,额外查询条件及相关表,排序
extra(self, select=None, where=None, params=None, tables=None,
order_by=None, select_params=None)
a.映射
#select
#select_params=None
#select 此处 from 表
b.条件
#where = None
#params=None,
#select * from 表 where 此处
c.表
#tables
#select * from 表,此处 (笛卡尔积)
d.排序
#order_by=None
#select * from 表 order by 此处
models.UserInfo.objects.extra(
select={'newid':'select count(1) from app01_usertype where id>%s'},
select_params=[1,],
where=['age'>%s'],
params=[18,],
order_by=['-age'],
tables=['app01_usertype']
)
"""
select
app01_userinfo.id,
(select count(1) from app01_usertype where id>1) as newid
from app01_userinfo,app01_usertype
where app01_userinfo.age>18
order_by app01_userinfo.age desc
"""
-原生SQL语句
from django.db import connection,connections
cursor = connection.cursor() # connection=default数据
cursor = connections['db2'].cursor()
cursor.execute("""select * from app01_userinfo where id = %s""",[1])
row = cursor.fetchone()
row = cursor.fetchall()
-raw
-简单的其他操作
models.UserInfo.object.filter(id_in=[1,2,3])
= models.UserInfo.object.in_bulk([1,2,3]) # 主键查询
2.xss 攻击
-慎用 salf 和 mark_safe
-非要用,一定要过滤关键字
XSS攻击全称跨站脚本攻击
3.CSRF
4.模板引擎
-部分方法
-自定义方法
Day73
上节回顾:
1.数据库操作
-models.xxx.objects.create(title='xx')
-filter(id=1,name='ff')
-filter(id=1,name='ff').update()
-filter(id=1,name='ff').delete()
-all()
-.values()
-.count()
-values_list()
-values_list() # 反:小写表名__
-bulk_create()
-models.xx.objects.all().only('id'),查其他,再发一次请求
-F,
-filter().annotate().filter() 在前是where,在后是having
-extra:
-select={x:'1'}
-tables=['x',]
-where
-order_by
-params
-select_params
-filter(id__range=[1,3])
-exclude
-exsit
-raw()
-aggregate 整张表聚合
-filter(id_gt)
-filter(id__lt)
-filter(id__lte)
-filter(id__gte)
-ilter(id__in=[1,2])
-first()
-last()
-defer() 查除了指定字段之外的
-max,min,count,sum,avg
-reverse
-distinct
-get()
-dates
-filter(age__isnull=True) 判断为空
-using
1.增
create(name='xx',age='xx'....)
dic={name:'xx',age:'xxx'}
crate(**dic)
2.更新
3.查询
ps:Django 帮助我们数据转换 -> 字典 => Form组件(用户请求规则验证+数据字典))
======================================补充1==================================
性能上的:
select_related查询主动做连表:数据量比较少
q = models.UserInfo.objects.all().select_related('ut','gp') # 加入有10条数据,在没有select_related时需要访问11此数据库
# select * from userinfo
# select * form userinfo inner join usertype on ...(对应select_related一次就关联查询出来)
for row in q:
print(row.name,row.ut.title)
外键:
1.节省内存空间
2.约束
perfetch_related: 不做连表,做多次查询:数据量比较多,查询比较频繁。因为连表会有损耗
q = models.UserInfo.objects.all().perfetch_related('ut','gp')
# select * from userinfo;
# Django内部:ut_id=[2,4]
#select * form usertype where id in [2,4]
# for row in q:
print(row.name,row.ut.title)
======================================补充2==================================
1.ManyToManyField
2.自定义关系表
3.杂交
今天内容:
1.CSRF
跨站请求伪造,你访问服务器时
a.基本应用
form表单中条件
{% csrf_token %}
b.全部禁用
c.不禁用,部分禁用
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
d.全部禁用,局部使用
from django.views.decorators.csrf import csrf_protect
@csrf_protect
e.特殊CBV
Ajas提交数据时,携带CSRF:
a.放置在data中
b.放在请求头里面,jQuery.cookie.js document.cookie $.cookie('csrftoken');
2.模板引擎
3.中间件
Day74
上节回顾:
-操作
-增删改查
-filter(**{k:v,k1:v1}),update(),create()
-all() values() values_list
-FK
正向:
filter() values,values_list() -> 跨表 fk__xxx
objs = all()
for obj in objs:
obj.fk.
反向:
filter() values,values_list() -> 跨表 表名称__xxx
objs = all()
for obj in objs:
obj.表名称_set.all()
-M2M
M2M 自定义 M2M+自定义
正向(M2M):
obj =
obj.m.add()
obj.m.remove()
obj.m.set()
obj.m.clear()
obj.m.all()
反向:
obj...
obj.表名小写_set.add()
...
M2M+自定义
obj.m.all()
obj.m.clear()
CSRF: POST时,需要用户携带随机字符串。如果没有,黑客会带有客户端的kooie去访问服务器
XSS:跨站脚本攻击
Cookie:
-放在用户浏览器端的键值对
-可以放很多,但是对于敏感信息不要放
创建超级用户:>python manage.py createsuperuser
models的操作
字符串:(在发送给数据库之前,在django正则验证)
EmailField(CharField)
...
a.直接通过
models.Userinfo.objects.create(...)
b.影响Django自带的管理工具admin
时间类:
DateTimeField(null=True)
数字:
DecimalField(max_digits=30,decimal_places=10) # 精准
枚举(Django):
color_list = (
(1,'黑色'),
(2,'白色'),
(3,'蓝色')
)
color = models.IntegerField(choices=color_list)
1.自己操作
自己取,自己用
2.给Django admin使用
应用场景:选项固定
ps:FK动态选择
字段:(必须要背会)
username = models.CharField(max_length=32)
ctime = models.DateTimeField(null=True,unique_for_date='8') # 局部创建索引
date = models.DateField()
cid = models.IntegerField()
nid = models.DecimalField()
# 枚举
color_list = (
(1,'黑色'),
(2,'白色'),
(3,'蓝色')
)
color = models.IntegerField(choices=color_list)
参数:
null = TRUE
default = 'xx'
db_index = True
unique = True
primary_key = True
max_length = 12
class Meta:
# unique_together = (
# ('email','ctime')
# )
index_together = (
('email','ctime')
)
考虑DjangoAdmin:
字段:
做正则验证
邮箱
IP
URL
UUID
...
参数:
blank
error_message={}
validators={
自定义正则
}
今日内容:
1.模板
-母版 一个子版仅有一个母版
页面继承
-include
导入的小组件
-函数 -> 不用加括号,自动执行,不能加参数
-模板自定义函数:
-simple_filter
最多两个参数,方式: {{ 第一个参数|函数名称:“第二参数”}}
可以做条件判断
-simple_tag
-无限制:{% 函数 参数1 参数2 参数3 }
-不能作为件判断
2.中间件
3.session
Cookie是什么?
保存在客户端浏览器上的键值对
Session是什么?
保存在服务端的数据 (本质上是键值对)
应用:依赖cookie
作用:保存会话(web网站)
好处:敏感信息不会直接给用
浙公网安备 33010602011771号