Django 学习笔记

day 1 : 本质与配置

一、web 框架本质:
1.http 建立在tcp 之上;一次互通后断开,无状态,短链接
请求头:

b'GET / HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9

'
请求体:

2.服务端:
st = socket.socket()
st.bind(ip)
st.listen(5)
while Ture:
conn,addr = st.accept()
conn.send
conn.close
3.客户端(浏览器)
st = socket.socket()
st.connect
st.send
st.recive
st.close

4.静态页面
1.获取url
2.view 函数返回页面
3.发送断开链接

5.动态页面
1.获取url
2.model 获取数据
3.view函数获取模版,与数据渲染返回
4.发送断开链接
6.分类
包含 socket,路由,view----------Tornado
包含后两个 ----------------------wsgrief + Django
包含路由 ----------------------wsgrief + flask + janja2


Django
其他

二、Django 框架:

1.安装
1.1 cmd安装
pip3 install django
django-admin startporject xxxx
python manage.py startapp xxxx #切换到project 目录下
python manage.py runserver 127.0.0.1:8080(default=8000)
1.2 ide 安装

2.文件目录
project
app
settings.py 配置文件
urls.py 路由文件
wsgi.py 定义socket

3.配置文件settings.py
3.1 app注册
3.2 模版配置
TEMPLATES=["DIR":os.path.join(BASE_DIR,'TEMPLATES')]
3.3 静态文件配置(图片,css,js)
STATIC_URL = '/static/' #所有地址前缀
STATICFILES_DIRS =(os.path.join(BASE_DIE,"static"),) #逗号必须加

3.4 数据库配置
'ENGINE': 'django.db.backends.mysql',
'NAME':'dbname',
'USER': 'root',
'PASSWORD': 'xxx',
'HOST': '',
'PORT': '',
#init 文件中配置
import pymysql
pymysql.install_as_MySQLdb()

4.路由文件urls.py
4.1 路由函数
4.1.1
form django.shortcuts import HttpRequest,render,redirect
def test (requset):
处理
从requset 拿数据
requset.GET.get('')
requset.GET.getlist('')
returm HttpRequest('字符串')
returm render(requset,'静态文件',{变量字典})
returm redirect('跳转网址')



4.2 路由列表

urlpatterns = [
url('地址的正则表达式',路由函数) djiago1.x
re-path('地址的正则表达式',路由函数) djiago2.x
]



5. templates模版语言
#传变量,如果是函数,自动执行,返回返回值
{{msg}} ------{"msg":变量值} {"msg":变量值.索引}
#for循环
{%for i in tt%}
{%endfor%}
#if判断
{%if %}
{%else%}
{%endif%}
#母版继承
{%block%}{%endblock%}
{%extends%}{%block%}{%endblock%}
#内置函数
{%data|upper%}。。。。。
#自定义函数
1. app中创建 Templatetags目录,函数py,
2. from django import template
register = template.Library()
@register.filter
def upper(value):
return value.upper()
3. 模板中顶部
{% load 函数 %}

4. 应用
#.filter 传参时不留空格 可作为判断条件
#
{% value|upper:"name"%}

# include,小组件重用
{% include xx.html %}


1.下载到静态文件目录
2.引入<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
3.根据官网提供样式修改
4.响应式布局@media,对不同尺寸屏幕有不同效果
5.默认分隔为12格,栅格参数


day 6: cookie、session
一、后台管理布局
导航条,logo,侧栏,主体

二、Django 母版继承
模板中{%block name%}{%endblock%}
应用文档中 {%extends “母版.html”%}#必须放在文档顶部
{%block name%} #一般css,内容,js都放一个,
新内容
{%endblock%}

三、cookie
定义:浏览器中保存的键值对
用途:登陆验证
位置:请求头
获取:request.COOKIES.get('')
操作:obj = redirect() obj.set_cookie('','',max_age=10,path=''#限制符合的路径,domain=)
签名加密: .set_signed_cookie(salt='')
自定制签名:该写类,用hash,md5加密
重复确认:装饰器
def fun(wrapper):
@funtools.wraps(wrapper)#确保函数属性不变
def inner(*args, **kwargs):
do something
res = wrapper(args, **kwargs)
return res
return inner
中间件 判断URL 是否需要验证

四、 session

定义: 服务器中保存的数据
用途: 保持会话
应用: 基于cookie
格式: 随机字符串:{用户数据}
使用:
request.session['']=''

存储: django 五种:数据库,缓存,缓存+数据库,加密cookie,文件,

day 7: 路由 orm

一、web框架介绍
project

1.路由
2.视图(orm)cbv,fbv
3.模版
app
1. admin
2. models 数据库
3. tests 单元测试
4. views 业务处理



二、路由系统


1. 百度seo影响:
get 传参 影响seo,所以配合正则匹配url可以提高seo
url.html 伪静态网页

2. view 接受参数
/fun/a1/a2
def fun(request,a1,a2)

/fun/(?P<a1>w+)/(?P<a2>w+)
def fun(request,a1,a2) #形式参数,两种方式不可混用


3. 精确结尾 :
test/
test$(推荐)

4. 路由分发
include(app/,'app.urls')
default 到index页面

5. 反向生成url(通过命名,Django特有)

urls文件中: re_path('',fun,name=test)
views文件中:
import reverse
result = reverse('test',args=(),kwargs={})
模板文件中

{% url 'test' 变量1 变量2 %}




三、orm

1. 配置
默认数据库 SQLlite

mysql ---- mysqldb 模块 (默认)python3 支持情况不好

修改成 pymysql 模块 project init文件中 pymysql.install_as_MySQLdb()


models 文件中放代指表格的类
views 文件中导入类操作类,进而操作数据

2. 创建表格,修改表格:
1)创建类
class User(models.Model):
#字段
id = AutoField( primary_key=True)
BigAutoField(primary_key=True)
username = models.CharField(max_length=64)
list = ((0,'user1'),(1,'user2'))
username = models.IntegerField(choose=temple) # get_username_diaplay 显示数字对应字符
username = models.DecimalField()
username = models.DatetimeField()
username = models.DateField()

#外键
ug = models.ForeignKey('Users',null=True)
models.OneToOneField
models.ManyToManyField

#参数
null ,
default,
unique,
db_index,
max_length,
primary_key,

#元信息
class Meta():
# 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
db_table = "table_name"
# 联合索引
index_together = [("pub_date", "deadline"),]
# 唯一联合索引
unique_together =[(nid,username),]



2) 执行命令
终端执行
python manage.py makemigrations
python manage.py migrate



3. 单表操作


from app01 import models

obj=models.User.object.create(name='xhk')

obj=models.User(name='xhk')
obj.save()

objs=[obj=models.User(name='xhk'),obj=models.User(name='xhk')]
models.User.object.bulk_create(objs,10)


models.User.object.delete()


models.User.object.update(name='')



result=models.User.object.all().count()
#查看原始语句
result.query

#where(行),having

models.User.object.filter(id=1,name='44') ---------> <QuerySet [对象,对象]>
con ={id:1,name:'44',}
models.User.object.filter(**con)

#列
models.User.object.all().only("id")
models.User.object.all().differ("name")

#选数据库

models.User.object.all().using('db')


#id 不等于1
models.User.object.exclude(id=1)


#orderby
models.User.object.all().order_by('id','name')

#desc
models.User.object.all().order_by('-id')

#groupby
from django.db.models import Count, Min, Max, Sum
models.User.object.value('id').annotate(Count(1))


models.User.object.all().values('id','value') ---------------------------------> <QuerySet {'id':id,'name':name}> 字典

models.User.object.all().values_list('id','value')------------------------------> <QuerySet ((id,name),(id,name))> 元祖

双下划线

models.User.object.filter(id__gt=1)
models.User.object.filter(id__lt=1)
models.User.object.filter(id__gte=1)
models.User.object.filter(id__in=[1,2,3])
models.User.object.filter(id__range=[1,10])
models.User.object.filter(name__startwith='xhk')
models.User.object.filter(name__endwith='xhk')
models.User.object.filter(name__contains='xhk')


F , Q ,extra :


form django.db.models import F,Q
# 获得之前的数据
models.User.object.all().update(age=F('age')+1)


#或 条件
models.User.object.filter(Q(id=1)|Q(id=2))

#构造复杂查询条件

q1 = Q()
q1.connector = 'OR'/'AND'
q1.children.append((id__gt=1))
q2 = Q()
q1.add(q2,'AND')

# 多填充一列
models.User.object.all().extra(
'n':
"
select * from user where id = %s

"
select_params =[1,],
where=[] #多个条件
params=[]
tables=[]#
order_by=[]
)

原生sql 语句

from django.db import connection, connections
cursor = connection.cursor() # cursor = connections['default'].cursor()
cursor.execute("""SELECT * from auth_user where id = %s""", [1])
row = cursor.fetchone()



4. 连表操作
一对一 OneToOneField

A:
B:有 OneToOneField字段 ,B创建数据时从A中选一个,

从A 拿 B 信息: A. B在数据库中表名 .列
从B 拿 A 信息: B.代表A的外键列 ----A对象
B.代表A的外键列_id --数字

#本质模拟 A 加了一列 列名为B,值为对象 的列
# B 外键列 存的是对应A的id 和对象



一对多 ForeignKey
A:
B:有 ForeignKey 字段,B创建数据时从A中选一个,
从A(某个对象) 拿 B 信息: A. B在数据库中表名_set .列
从B 拿 A 信息: B.代表A的外键列 ----A对象
B.代表A的外键列_id --数字


#本质模拟 A 加了一列 列名为B,值为有关对象的集合 的列
# B 外键列 存的是对应A的id 和对象

自关联:

树形评论


多对多 ManyToManyField (Django自带,局限)

自关联(好用!)





小结

1) 外键代表一行数据,通过. 正向取得


2) 无外键的字段 通过 .对象表_set.all() 反向取得




3) 后两种 values,values_list 可以用 '外键__目标' 做连表


4) 减少查询次数:
values('外键__目标').all()
select_related 主动连表减少数据表查询操作 innerjoin
prefetch_related 多次单表查询加快查询速度



day 8 : 分页,csrf

一、CBV FBV
from django.views import View
from django.utils.decorators import method_decorator
@method_decorator(index) #cbv 装饰器


CBV class cc (View)
get(self,request):

return

post(self):

return

url('',views.cc.as_view())



二、分页

1. django 自带分页

view中
from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage
cpage = request.GET.get('page')
cpage = request.GET.get('page')
data = models.Users.objects.all()
paginator = Paginator(data,10)
try:
page = paginator.page(cpage)
except PageNotAnInteger as e:
page = paginator.page(1)
except EmptyPage as e:
page = paginator.page(1)
return render(request,'index.html',{'page':page})

模板中:
<div>
{% if page.has_previous %}
<a href="/index/?page={{ page.previous_page_number }}">上一页</a>
{% endif %}

{% for num in page.paginator.page_range %}
<a href="/index/?page={{ num }}">{{ num }}</a>
{% endfor %}

{% if page.has_next %}
<a href="/index/?page={{ page.next_page_number }}">下一页</a>
{% endif %}
</div>



2. 自己开发分页组件
类文件处理返回对象
views文件中:类接受参数,page,data,每页显示数量,显示页码数量
模板中 上一页 循环数据,下一页


三、 多对多操作 (两列)

1. m = ManyToManyField('girl')

obj = models.boy.object.first()
obj.m.add(1,5) (*[1,2])
obj.m.remove()
obj.m.ser([]) #重置,可迭代对象
obj.m.all() #第二张表有关对象列表
obj.m.clear() #清除所有

2.反向取得
obj = models.gril.object.first()
obj.boy_set.all() #


四、 CSRF (请求防伪)

1. XSRF攻击(跨站请求伪造)

{% csrf_token %} #生成input 标签

#全站禁用

注释中间件

#局部禁用

from django.views.decorators.csrf import csrf_exempt,csrf_protect
@csrf_exempt
def view

#局部应用
@csrf_protect
def view

#ajax 验证

1. 获取input name , 值
2. jquerycookie 获取cookie 值



2. XSS攻击(跨站脚本攻击)
django 默认防止,字符串是否可以当作html解释
view文件中 :
from django.utils.safestring import mark_safe

newstring = mark_safe(string)

模板文件中 : |safe


day 9 中间件


一、中间件
1. HTTP 生命周期:
request请求 ----> wsgi --> 中间件的request 函数 ----> 找到视图函数 ----> 中间件的view函数 ----->视图函数 -----》 respond的view函数

---》respond的respond函数 ---》wsgi ---》 浏览器解释

2. 格式:

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class test(MiddlewareMixin):
def process_request(self,requset):
print('执行 process_request')
return HttpResponse('stop')

def process_view(self,request,)

def process_response(self,request,response):
print('执行process_response')
return response

def process_exception()


二、WSGI(Web Server Gateway Interface)

Django 默认 wsgiref(本地测试) uwsgi(工作)

一套标准:函数名,参数名相同,
本质 socket 和 处理请求头使其符合django格式


三、MTV 和 MVC (功能划分)


day 10 Form 组件

一、 form 标签现有问题:
1. 无法记住上一次提交状态
2. 需要重复验证数据有效性

二、 Django form 组件

1. 范例
写类
from django.forms import Form,fields

class Test(Form):
user = fields.CharField(required=True,min_length=6,max_length=16,error_messages={
'required':'你他妈倒是写啊','max_length':'你闲着没事干打这么多字啊','min_length':'你太短了!'

})
password = fields.CharField(required=True,min_length=6,max_length=16)
使用:

res = Tset(request.POST)
res.is_valid()
res.clean_data
res.errors



2. 验证原理:

1. self.fields ={

'user':对应字段,
'password':对应字段,}

2. 循环 字典

flag:
error_messages
clean_data




3. form 表单提交 和ajax 相同 # 二选一

ajax 拿回 错误信息:json.dumps(answer) 里面有 status,errors
显示 : 创建新标签,循环放入信息,(清除之前的报错信息)

4. 常用字段(本质正则表达式)

Charfield
IntegerField
Emilfield
URLfield
SLUgfield 字母数字下划线(去除特殊字符)
DateField
DatetimeField
RegexField()
widget类

5. 常用属性
required=True, 是否允许为空
widget=None, HTML插件 (种类)attr={}(定制样式)
label=None, 用于生成Label标签或显示内容
initial=None, 初始值
help_text='', 帮助信息(在标签旁边显示)
error_messages=None, 错误信息 {'required': '不能为空', 'invalid': '格式错误'}
show_hidden_initial=False, 是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直)
validators=[], 自定义验证规则
localize=False, 是否支持本地化
disabled=False, 是否可以编辑
label_suffix=None Label内容后缀

6. 下拉菜单的实现
单选:integerfield + select // choicefield + select
多选 multiplefield + selectmultiple
动态更新: 重新定义init函数,在其中重新去取值
def __init__(self,*args,**kwargs):
super(Test,self).__init__(*args,**kwargs)
self.fields[].widget.c
django 自带功能
from django.forms import models as form_models
xx = form_models.ModelMultipleChoiceField(queryset=models.UserGirl.objects.all())

def __str__:
return xx.xx

7. 钩子
def clean_字段名(self):# 必须有返回值,否则为None
return


def clean (self) #所有字段验证完执行,return 新的处理后数据
return somethin


day 11 Ajax上传 (图片异步上传,预览)


一、 Ajax:

0. 定义:AJAX,Asynchronous JavaScript and XML (异步的JavaScript和XML),一种创建交互式网页应用的网页开发技术方案。
用途: 1、注册时,输入用户名自动检测用户是否已经存在。
2、登陆时,提示用户名密码错误
3、删除数据行时,将行ID发送到后台,后台在数据库中删除,数据库删除成功后,在页面DOM中将数据行也删除。
实现方式:
1. 原生Ajax
2. jquery ajax
3. 利用iframe + js 伪造



1. 原生通过XTML HTTPRequests 对象实现
模板中 :var test = new XMLHTTPRequest();
test.onreadystatechange = function(){
if (test.readystate === 4){
do something

}

}
test.open('POST','url);
test.setReaqusetHeader('Content-Type','application/x-www-form-urlencoded')
test.send('i=123&h=123')
test.responsetext
视图中:
常规


2. jquery ajax
模板中 : function test() {
$.ajax(
{
url:'/test/',
type:'POST',
data:$('#f1').serialize(),
dataType:'JSON',
success:function (arg) {
console.log(arg.answer,typeof arg)
}
}

)
视图中: 错误信息从字典dumps成字符串

3.伪造
1.表单内容发往 iframe 由iframe 提交
2.由a标签 绑定函数 实现数据传送到后台:
1. 提交表单内容
2. 绑定iframe onload加载事件

3. 拿回数据
iframe.contentWindow.document.body.innerText


二、基于Ajax上传文件

1. 原生Ajax 通过formdata 对象实现:

1.实例化得到 formdata 对象作为文件载体,append文件名和文件
2.实例化得到 XTML HTTPRequests对象作为运输载体,设置回调函数,url,post,send formdata对象
3.后台 post.files.get(文件名),大文件通过chunks分割,循环写入



2. jquery ajax
同理:
formdata对象 作为文件载体,jquery ajax 作为运输载体
另加上:contentType:false,processData:false 减去jquery自带的request头处理



3. 伪造(兼容性最好)

form 表单添加属性 enctype="multipart/form-data",target到iframe,为提交按钮绑定提交,加载完成事件

三、跨域Ajax:JSONP

定义:JSONP(JSONP - JSON with Padding是JSON的一种“使用模式”),利用script标签的src属性(浏览器允许script标签跨域)

原理:浏览器同源策略

禁止非同源站点信息;带有src属性的一般不禁止,如<script>
解决方案:
1.发送请求返回函数名和参数,参数为真实信息,放入浏览器内存
本地通过调用函数,获得参数内信息
2. 服务器发起请求,返回给客户端

实现:

url ?callback= 函数名
function 函数名(arg){}

服务端,获取 request.GET.get(callback)
return 函数名(真实内容)

jquery实现:
dataType:'JSONP'
jsonp:'callback'
jsonpCallback:'test'
四、 CORS

定义:跨域资源共享(CORS,Cross-Origin Resource Sharing)
本质:设置响应头,使得浏览器允许跨域请求。
实现: 服务器返回响应头obj['Access-Control-Allow-Origin'] ='*'


day 12 报障系统项目

一、报障系统项目需求和亮点

1. 解决运维人员的工效数字化

2. 亮点为权限管理

二、 流程

1. 需求分析
2. 数据库设计
3. 页面设计(UI)

三、 主站

四、 图形验证码

1. 静态src
2. 写动态url

动态创造图片
from PIL import Image
from io import BytesIO
f = BytesIO()
img = Image.new(mode='RGB',size=(120,130),color=(175,255,255))
img.save(f,'png')
data = f.getvalue()

return HttpResponse(data)
点,线,圆,字,特殊字(引入字体文件ttf),随机大小,颜色,引入random

五、 注册页面
见流程图


六、 文章分类筛选


七、 层级回复

八、 权限系统




day 13 CMBD

一、背景设计

二、采集


三、 api


四、 后台管理


五、 增删改查插件


六、 restful API


day 14: 消息队列,堡垒机,git

一、rabbitmq 消息队列
1. 作用:
存储信息,数据
保证顺序
保证交付





二、git
定义:分布式版本控制系统
起源:linux创始人为了抵制收费的版本所写,为了管理linix版本
与svn 区别:
1. 分布式无需中央服务器支持,每人都有版本仓库
2. git 内容按照元数据方式(中继数据,描述数据的数据)存储,svn普通目录
3. git 分支功能强大
4. git 无全局版本号
5. git内容完整性更强,采用SHA-1哈希算法
基本命令:
1. git init
2. git add
3. git commit (-a ) -m
4. git rm
5. git rm --cached <file>
6. git reset HEAD
7. git status
8. git diff
9. git mv
10. git log
11. git tag -a v1.0
12. git reflog
13. git stash


发布版本:
1. git clone
2. git push
3. git pull
分支与合并
1. git branch (-d) test
2. git checkout master(主分支,第一个分支)
3. git checkout .
5. git checkout HEAD .
5. git checkout --file
4. git merge

git工作流程:
1. 克隆git资源作为工作目录
2. 在此基础上更改
3. 如果其他人修改,你可以更新
4. 提交前查看
5. 提交
6. 提交后发现错误,撤回提交再次修改
git 分区:
1. 工作区:实际目录
2. 缓存区:.git中的index
3. 本地版本库: .git 内部有 index object等文件
git 修复bug 方式:
1. stash
2. 分支








三、 堡垒机

























原文地址:https://www.cnblogs.com/xinghuaikang/p/calvin_xhk.html