文章目录
第一章:Django入门篇
一、 web应用
1 通过浏览器访问程序的应用
2 客户端:浏览器 服务端:还是原来的服务端
3 cs架构,bs架构
-client server
-浏览器 服务端:本质就是cs
4 web应用就是bs架构的软件
-client端:浏览器,app,微信小程序
-web应用流行(优点)
-客户端都用浏览器
-节约客户端资源
-更新再服务端完成,客户端不需要操作
-缺点
-ie,谷歌,火狐,不兼容
-服务端出错了,程序无法使用
-公司倒闭,服务端停止,资料没了
5 浏览器中输入地址,如果不写端口号,就是80
6 动态页面和静态页面
-动态页面:每次访问数据都有可能变
-静态页面:死页面,不管访问多少次,都不会变化
7 web框架是什么?
-别人帮我们封装好一些代码,方便我们写web应用,我们只需要再固定的位置写固定的代码即可
-python中的主流web框架
-django框架(大而全)
-flask框架(小而精)
-tornado(异步框架,性能高)
-Sanic:3.5及以上,不能运行在windows上,FastApi(异步框架)
-任何后端语言都有web框架
-java:ssh,ssm,springboot,springCloud
-go:beego(中国人,python界的django),gin(python界的flask)。。。
二、HTTP协议(重要)
1 应用层协议:有一些规范
-请求协议
-响应协议
2 http协议特性(特点)
-基于TCP/IP协议之上的应用层协议
-基于请求-响应模式(服务端主动向客户端推送消息:长轮询,websocket协议)
-无状态保存(会话保持,cookie)
-无连接
请求协议
GET /favicon.ico HTTP/1.1\r\n # 请求首行:GET请求方式 请求地址 http版本(0.9,1.1,2.0)
# http版本:性能越来越高
### 往下都是请求头:User-Agent:客户端类型 Referer:上一次请求的地址(图片防盗链)
Host: 127.0.0.1\r\n
Connection: keep-alive\r\n
Pragma: no-cache\r\n
Cache-Control: no-cache\r\n
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"\r\n
sec-ch-ua-mobile: ?0\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36\r\n
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8\r\nSec-Fetch-Site: same-origin\r\nSec-Fetch-Mode: no-cors\r\nSec-Fetch-Dest: image\r\n
Referer: http://127.0.0.1/\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n\r\n
### 请求体\r\n\r\n下面
....如果发送post请求
### 快速记忆:请求首行,请求头,请求体
响应协议
### 响应首行,响应头,响应体
## 响应首行
HTTP/1.1 200 OK\r\n # http的版本号,响应状态码和标志
### 响应头
cache-control: no-cache, no-store # 不启用缓存
content-encoding: gzip # 使用gzip压缩
### 响应体(真正在浏览器中看到的)
html+css+js:看到千奇百怪的页面
响应状态码
1xx:请求正在处理
2xx:请求成功
3xx:重定向
4xx:客户端错误 403 404
5xx:服务端错误 代码出错了
URL简介
统一资源定位符(url): 是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。
互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它
# 格式:
协议://IP:端口(80)/路径?name=lqz&age=18
?之前的是请求路径,?之后的是请求数据部分
三、django简介
1 MVC与MTV模型(不同分层模式下的叫法不一样,本质都是分层)
-mvc:web的一种开发模式,分层模式
-m:model:数据处理
-v:view,视图
-c:controler,控制器
-MTV:web的一种开发模式,分层模式(本质也是mvc)
-M:model,数据处理,就是mvc的M
-T:Templagte,它是mvc的V,view
-V:视图函数层,Django的V+路由是MVC的c层
2 安装django
-1.x(老项目用),2.x(主流),3.x(最新,用的少)
-安装方式
-命令行下:pip3 install django==2.0.7
-使用pycharm装
3 django安装完成,在解释器路径下的scripts文件夹下会有一个可执行文件django-admin.exe
-创建django项目,需要使用
4 创建一个项目
-django-admin startproject 项目名
-使用pycharm直接创建
-写项目名,不要使用虚拟环境,建一个app01
5 环境变量
-在cmd下敲一个命令,是否会执行取决于,你这个命令是否在当前路径下,如果当前路径下没有,会去环境变量下诏
-确认好你敲的命令,到底是哪个环境变量下的可执行文件
-可能会出的问题:pip install的时候,模块装在了其它解释器中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-18WJmR4b-1624881522407)(assets/1624774224327.png)]
3.2 目录介绍
myseconddjango # 项目名字
-app01 # app的名字
-migrations # 以后涉及到数据库表的更改,这里会有记录
-__init__.py
-__init__.py # 包下的init文件
-admin.py # django是一个大而全的框架,它会有一个后台管理,后台管理相关(目前不用管)
-apps.py # 每一个app都会有这个py文件,配置相关(不用管)
-models.py # MTV中的M这一层,数据库相关的写在这里(很重要)
-tests.py #测试相关(不用管)
-views.py # MTV中的V这一层,视图函数(业务逻辑写在这里,很重要)
-myseconddjango
-__init__.py
-urls.py # 所有的路由(路径和视图函数的对应关系)
-settings.py # 整个项目的配置文件
-wsgi.py # 上线相关(目前不用管)
-templates #文件夹,模板文件放在这里面(index.html,home.html)MTV架构的T层,Template
-manage.py # 启动的入口,命令的执行
##app概念介绍
-一个项目中,可以有多个app(一所大学(项目),大学中有很多学院(app))
-开发了一个淘宝
-订单板块
-用户板块
-商品板块
-物流板块
-一个项目中至少有一个app
-创建app 的命令
-如果用pycharm创建的项目,第一个app,直接就会创建出来
-后期想再建几个app,使用如下命令
-python3 manage.py startapp app名字
3.3 启动项目
# 方式一(命令行下)
python3 manage.py runserver
python3 manage.py runserver 127.0.0.1
python3 manage.py runserver 127.0.0.1:8080
# 方式二(常用)
-点击pycharm右上角的绿色箭头
3.4 简单示例
# 用户访问 index路径,返回一个 helloworld
3.4 静态资源引入(很重要)
# 第一步:在项目根路径新建static文件夹
# 第二步:在文件夹中新建css,js,img。。。文件夹
# 第三步:setting.py中加入
STATIC_URL = '/static/'
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'static'),
]
# 第四步:在模板文件中使用
<img src="/static/img/111111.jpg" alt="" height="80px" width="80px">
<link rel="stylesheet" href="/static/css/common.css">
3.5 django请求生命周期
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gKOmc4vu-1624881522410)(assets/1624778786052.png)]
四、路由控制(次重要)
# 作用:客户端请求的地址和视图函数的映射关系
# urls.py中写的为什么能批匹配,本质原因是setting.py中的ROOT_URLCONF = 'myseconddjango.urls'
#
4.1 从路径中解析出参数传递给视图函数
# 方式一:path 5种转换器
#slug,匹配字母、数字以及横杠、下划线组成的字符串。
#uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
#path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
# test/193333
# path('test/<str:id>',views.test),
# path('test/<int:id>',views.test),
# path('test/<slug:id>',views.test),
# path('test/<uuid:id>',views.test),
# path('test/<path:id>',views.test),
#test/lqz/888
# path('test/<str:name>/<int:id>',views.test),
### 方式二:使用re_path (了解即可),老版本,1.x版本用的多,2.x版本使用path多
# test/asdfasf
# re_path('test/(?P<name>\d+)',views.test),
4.2 路由分发
### 重点,如果你新建了一个app,一定要在配置文件中注册
INSTALLED_APPS = [
'app01.apps.App01Config',
'app02.apps.App02Config',
# 'app02'
]
### 如何使用
## 第一步,在主路由中
urlpatterns = [
path('app01/',include('app01.urls')),
path('app02/',include('app02.urls')),
]
## 第二步,在不同app中新建urls.py,在其中写
# 假设在app02下
urlpatterns = [
path('index/', views.index),
]
## 第三步:当浏览器访问
/app02/index----》触发app02这个应用的urls.py执行
4.3 反向解析
## 通过别名获得真正的地址,在试图函数中使用
def reverse_test(request):
res=reverse('home') # 反向解析的函数
print(res)
return redirect(res)
4.4 django1.x的路由(了解)
# path,re_path 都是2.x才有的,1.x版本没有
# 1.x上只有一个url,就是2.x的re_path
4.5 path。re_path中的kwargs的作用
# 向试图函数传递默认参数
## 总结:可以向视图函数传递参数的方式
-path: <str:name>
-re_path: /test/(?P<name>\w+)
-path,re_path的kwargs参数传递
五、视图层(次重要)
#### 重点:如果post提交数据,显示403 ,先去配置文件中,4,5十行,注释掉 'django.middleware.csrf.CsrfViewMiddleware',
print(request.method) # 请求方法 GET,POST,DELETE,PUT。。。
print(request.path) # 请求路径
print(request.get_full_path()) # 请求全路径,连请求数据也有
print(request.GET) # get请求携带的数据,当成一个字典
print(request.GET.get('name')) # get请求携带的数据,当成一个字典
print(request.POST) # post请求携带的数据,当成一个字典
print(request.body) # 请求体的内容,二进制
print(request.META) # 请求头中的数据(User_Agent,Refer,客户端地址)
# request.META.get('HTTP_USER_AGENT')
# request.META.get('REMOTE_ADDR') 客户端地址
#
print(request.FILES) # 文件
print(request.is_ajax()) # 判断当次请求是不是ajax请求
5.2 文件上传案例
html模板内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
如果是上传文件,一定要指定:enctype="multipart/form-data"
<hr>
<form action="" method="post" enctype="multipart/form-data">
<p>文件上传:<input type="file" name="myfile"></p>
<input type="submit" value="提交">
</form>
</body>
</html>
视图
def test_file(request):
if request.method == 'GET':
return render(request, 'file_upload.html')
else:
myfile = request.FILES.get('myfile') # 从上传的文件中,根据名字取出文件对象
# 保存到本地即可
with open(myfile.name, 'wb') as f: # 本地打开一个空文件,一行行读上传上来的文件,把上传的文件存到空文件中
for line in myfile:
f.write(line)
return HttpResponse('文件上传成功')
补充
1 前端向后端传递数据,的几种编码格式
-默认编码:url-encoded
name=lqz&age=18&hobby=ss
-上传文件的编码:form-data
比较复杂
文件从request.FIELS中取
数据从request.POST中取
-json格式(前后端分离用的多)---->json格式的编码方式从request.POST中取不出数据,自行从body中取出
{"name":"lqz","age":"19"}
六、模板层(次重要)
1 templates 文件夹下的 xx.html 模板页面
2 纯粹的html只能包含HTML,css,js
3 咱们的模板文件包含了python代码
4 模板语法:dtl
视图
def template_test(request):
name = '刘亦菲'
dic={'name':'lqz','age':18,'hobby':{'name':'篮球'}}
li=['张三','李四']
ll2 = [
{'name': 'lqz', 'age': 18},
{'name': 'lqz2', 'age': 19},
]
class Person:
name='lqz'
age=19
def __str__(self):
return self.name
p=Person()
def test():
print('test')
return "函数执行完了"
import datetime
now = datetime.datetime.now()
# return render(request, 'template_test.html', {'name': name,'dic':dic,'li':li,'l':ll2,'test':test})
return render(request, 'template_test.html', locals()) # 把当前作用域下的所有变量,在模板中都可以使用
def template_base(request):
return render(request,'order.html')
def template_base1(request):
return render(request,'user.html')
模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板语法</title>
<script src="jquery.min.js"></script>
</head>
<body>
<h1>模板语法</h1>
我的名字是:{{ name }}
<hr>
<br>
字典是(通过.深度取值):{{ dic }}
<br>
名字是:{{ dic.name }}
<br>
年龄:{{ dic.age }}
爱好:{{ dic.hobby.name }}
<br>
<hr>
取出张三的名字:{{ li.0 }}
<hr>
取出年龄:{{ l.0.age }}
<hr>
执行函数:{{ test }}
<hr>
对象的属性{{ p.age }}
<hr>
<h2>过滤器(内置过滤器)</h2>
时间是 :{{ now }}
<br>
时间是 :{{ now|date:'Y-m-d H:i:s' }}
<p>如果有值就显示,没有值就显示 数据为空 {{ name |default:'数据为空' }}</p>
{#计算长度,只有一个参数#}
<p>{{ ll2 |length }}</p>
计算文件大小
<p>{{ 102478456 |filesizeformat }}</p>
{##}
字符串切片,前闭后开,前面取到,后面取不到
<p>{{ 'hello world lqz' |slice:"2:-1" }}</p>
<p>{{ 'hello world lqz' |slice:"2:5" }}</p>
{##}
{#截断字符,至少三个起步,因为会有三个省略号(传负数,1,2,3都是三个省略号)#}
<p>{{ '刘清政 world lqz' |truncatechars:"5" }}</p>
{#截断文字,以空格做区分,这个不算省略号#}
<p>{{ '刘清政 是 大帅比 谢谢' |truncatewords:"1" }}</p>
<h2>标签(for)</h2>
{% for foo in ll2 %}
<p>{{ forloop.last }}</p>
<p>名字是:{{ foo.name }}</p>
<p>年龄:{{ foo.age }}</p>
<hr>
{% endfor %}
<h2>标签(if)</h2>
{% if name %}
名字是:{{ name }}
{% else %}
没有名字
{% endif %}
<h2>模板的导入和继承</h2>
{% include 'left.html' %}
</body>
</html>
作者:吴常文
出处:https://blog.csdn.net/qq_41405475
本文版权归作者和CSDN共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。