Django框架从入门到高级
(一)Django入门
Web应用
详细地址见:https://blog.csdn.net/DiligentGG/article/details/126606099?spm=1001.2014.3001.5501
- Web框架本质
web框架本质上可以看成是一个功能强大的socket服务端,用户的浏览器可以看成是拥有可视化界面的socket客户端。两者通过网络请求实现数据交互,从架构层面上简单的将Web框架看做是对前端,数据库的全方位整合。
web框架可以理解为是基于互联网的web服务端(socket服务端)
纯手撸一个web框架
1.步骤
- socket服务端代码
- HTTP协议
- 根据网址后缀的不同请求不同的内容
- 请求方式:GET:朝服务端索要数据;POST:朝服务端提交数据
- 从请求数据格式中筛选出用户输入的网址后缀
2.代码存在缺陷
- socket代码重复编写轮子
- 针对请求数据格式的处理复杂且重复
- 针对不同的网址后缀的匹配方式过于简单
3.基于wsgiref模块
wsgiref模块解决了两个问题:socket代码重复编写造轮子和针对请求数据格式的处理复杂且重复。
动静态页面
动态页面的页面上数据是动态获取的,反之静态页面数据是写死的。
需求:
将字典数据传递到前端页面并且想要操作字典数据。
遇到问题:无法自己实现在html页面上使用类似于后端语法操作数据,即引出jinja2模块。
jinja2模块
概念:
jinja2能够让我们在html文件内使用类似于后端的语法来操作各种数据类型。
基本语法:
控制结构 {% %}
for循环模板语法
{% for user in user_data %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.age }}</td>
</tr>
{% endfor %}
变量取值 {{ }}
普通模板语法
<h1>{{ data }}</h1>
<h1>{{ data['name'] }}</h1>
<h1>{{ data.get('pwd') }}</h1>
<h1>{{ data.hobby }}</h1>
注释 {# #}
python主流web框架之django框架
1.MVC与MTV模型(老刘博文编写,了解一下)
- MVC
Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器©和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求,其示意图如下所示:
- MTV
Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是值:
M 代表模型(Model): 负责业务对象和数据库的关系映射(ORM)。
T 代表模板 (Template):负责如何把页面展示给用户(html)。
V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template。
除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:
一般是用户通过浏览器向我们的服务器发起一个请求(request),这个请求回去访问视图函数,(如果不涉及到数据调用,那么这个时候视图函数返回一个模板也就是一个网页给用户),视图函数调用模型,模型去数据库查找数据,然后逐级返回,视图函数把返回的数据填充到模板中空格中,最后返回网页给用户。
2.django目录结构
- init.py:主要做一些冷门配置
- settings.py:项目配置文件
- urls.py:对应关系(即路由配置)【路由层】
- wsgi.py:django服务
- manage.py:django入口文件
- templates文件夹:存储项目所需要的html文件【模板层】
- migrations文件夹:orm相关(数据库打交道的记录)
- admin.py:django自带的后台管理
- apps.py:创建应用之后用于应用的注册
- models.py:存储与数据库表相关的类【模型层】
- test.py:自带的测试文件
- views.py:存储业务相关的逻辑代码(函数,类)【视图层】
- db.sqlite3:自带的小型数据库
3.django小白必会三板斧
三板斧 | 功能描述 | 备注 |
---|---|---|
HttpResponse | 主要用于直接返回字符串类型的数据 | return HttpResponse(‘你好’) |
render | 主要用于返回html页面,并且支持模板语法 | return render(request, ‘func.html’) |
redirect | 主要用于页面重定向 | return redirect(‘https://www.baidu.com’) |
4.静态文件及相关配置
- 静态文件概念:html页面上使用的不经常改变的资源(第三方框架文件;css文件;js文件;图片文件)
- 静态文件一般都会放在static文件夹下
- 针对静态文件资源的访问我们也需要提前开设相应的接口(考虑到静态文件资源不固定,所以应该在配置文件中配置。)
将项目同名文件夹下settings.py文件下配置:
STATIC_URL = '/static/' # 接口前缀
# 静态文件资源配置
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static')
]
5.请求方法
URL:统一资源定位符(简称网址)
- GET请求(两种 HTTP 请求方法之一):
朝别人索要数据,也可以携带额外的数据
GET请求没有请求体(HTTP数据格式) - POST请求:
朝别人提交数据,也可以携带额外的数据
数据都是在请求体中,并且数据大小没有限制
注意:form表单默认的数据提交方式是get;要修改为post时需要在form action字段中添加method字段。
<form action="" method="post">
- 参考博文:https://blog.csdn.net/dreamingbaobei3/article/details/95938517
6.request对象方法
- request.method:获取请求方式,结果是纯大写的字符串;
- request.POST:获取POST请求发来的普通数据(不包含文件)
request.POST.get() 默认只获取列表中最后一个数据值
request.POST.getlist() 获取键对应的整个列表 无论有几个数据值
- request.GET:获取url后面携带的非敏感数据
request.GET.get() 默认只获取列表中最后一个数据值
request.GET.getlist() 获取键对应的整个列表 无论有几个数据值
- 具体代码展示
def login(request):
'''该函数将来会通过不同的请求方式触发,并且需要执行不同的业务逻辑代码'''
# print(request.method)
if request.method == 'GET':
# 返回给前端一个登录页面
return render(request,'login.html')
elif request.method == 'POST':
# 获取用户提交的数据
# print(request.POST) # <QueryDict: {'username': ['jason'], 'password': ['123']}>
# res = request.POST.get('username') # jsaon <class 'str'>
print(request.POST) # <QueryDict: {'username': ['jason', 'kevin', 'oscar'], 'password': ['123']}>
res = request.POST.get('username') # oscar <class 'str'> 默认只会拿最后一个数据
res1 = request.POST.getlist('username') # 获取键对应的整个列表,无轮有几个数据值
print(res,type(res))
print(request.GET)
return HttpResponse("收到了")
django请求生命周期流程图
https://www.processon.com/diagrams
路由匹配
1.语法结构
path('网址后缀',函数名)
路由结尾的斜杠:
- 默认情况下不写斜杠,django会做二次处理。
第一次匹配不上,会让浏览器加斜杠再次请求 - django配置文件(settings.py)中可以指定是否自动添加斜杠。
APPEND_SLASH = False
2.path转换器
当网址后缀不固定的时候,可以使用转换器来匹配;
转换器匹配到的内容会当做视图函数的关键字参数传入;
转换器有几个叫什么名字,那么视图函数的形参必须对应。
3.re_path正则匹配
re_path(正则表达式,函数名)
- 匹配特性:
一旦网址后缀的正则匹配到的内容就会自动执行后面的函数。
并结束整个路由的匹配。
re_path('^text/$',views.test)
当网址不固定的时候可以使用转换器来匹配;
- 正则匹配之无名分组
re_path('^text/(\d+)',view.text)
正则表达式匹配到的内容会当做视图函数的位置参数传递给视图函数。
- 正则匹配之有名分租
re_path('^test/(?P<year>\d+)/(?P<others>.*?)/'views.test)
正则表达式匹配到的内容会当做视图函数的关键字参数传递给视图函数
4.反向解析
概念:页面上提前写死了很多路由,一旦路由发生变化会导致所有页面的连接失效;为了防止出现问题,我们需要使用反向解析。
原理:返回一个结果,该结果可以访问到对应的路由。
用法:
(1)路由对应关系起别名
path('register/',views.reg,name='reg_view')
(2)使用反向解析语法
在html页面<a herf" ">中修改
{% url 'reg_view' %}
(3)后端
from django.shortcuts import reverse
reverse('reg_view')
5.无名有名反向解析