1 初识Django
- Django在Python Web开发中是一个非常重要的Web框架,大而全且功能非常强大。
1.1 什么是框架:
在编程领域,通常会听到MVC框架。
实际上,MVC框架是基于MVC这种创建Web 应用程序的设计模式所开发出来的框架。
1.2 那么,MVC设计模式是什么样的呢?
先来看这个英文缩写每一个字母所代表的内容:
M: Model(模型)
V: View(视图)
C: Controller (控制器)
- Model(模型):
是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据。
- View(视图):
是应用程序中处理数据显示的部分,通常视图是依据模型数据创建的。
- Controller(控制器):
是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
MVC设计模式以及基于MVC的框架,大家可以自行查找相关资料进行深入的了解
这里之所以提及这个设计模式,是因为我们所使用的Django这个框架的设计模式与之非常相似
Django是标准的基于MTV设计模式的框架
1.3 Django的MTV模型分别代表:
M: Model(模型)
T: Templates(模板)
V: Views(视图)
-
大家看完上面的英文缩写所代表的内容,会发现多了一个Template(模板)却少了一个Controller (控制器)。
-
实际上并没有缺少Controller (控制器),Django框架本身承担了控制器的角色。
1.4 Django处理请求的顺序如下:
1、通过Web朋务器网关接口(WSGI:Web Server Gateway Interface)对Web朋务器的socket请求进行处理;
提示:WSGI是Python应用程序或框架和Web朋务器之间的一种接口。
2、Django框架(控制器)控制用户输入,进行URL匹配,通过映射列表将请求发送到合适的视图;
3、视图(Views)向模型(Model)和模板(Templates)发送或获取数据;
4、模型(Model)对数据库进行存取数据;
5、模板(Templates)用于将内容和展现分离,通过模板描述数据如何展现;
6、视图(Views)将模板和数据整合,形成最终页面;
7、Django框架(控制器)返回页面展示给用户。
此外,Django还有一个URL分发器。它的作用是将一个个URL的页面请求分别发给不同的Views处理,Views再调用相应的Model和Template。
- 大家可以通过下面这张图,了解Django处理请求的过程。
总结:
简单来说,Django是将每个URL的页面请求分发给不同的View(视图) 进行处理,View(视图)再调用相应的Model(模型)进行数据的保存或读取,并且View(视图)也会调用相应Template(模板),将Model(模型) 读取到的数据与Template(模板)进行整合,形成最终页面后返回给控制器,展示给用户。
下面让我们一起看看如何创建Django项目吧!
2、创建Django项目
2.1 打开PyCharm创建项目
- 2.1.1 先要下载Django:打开cmd,输入pip install django,等待安装完成即可
- 2.1.2 打开PyCharm创建项目
- 设置好项目路径、项目名称以及App名称之后,点击Create创建项目。
2.2 项目目录结构
- 当我们创建好项目后会看到以下的目录结构。
2.3 启动Django项目
- 点击pycharm界面中debug(那个小虫子)旁边的运行按钮,运行Django项目
- 运行成功之后,点击运行时输出的地址跟端口,复制到浏览器中打开,看到以下的界面之后说明Django项目已经运行起来了
这仅仅是Django的页面内容,如果想用Django开发一个真正可以访问的Web应用,我们需要在项目中创建一个新的应用。创建应用可以通过命令行进行创建。
2.4 Django创建App应用:
- 打开pycharm的终端中运行以下指令:
python3 manage.py startapp blog(应用名称)
例如,创建一个名称为“MySite”的应用,命令为:
python manage.py startapp MySite
2.5 先别急
- 既然我们使用了PyCharm这个开发环境,创建应用还有另外一种方式。
- 在工具(Tools)菜单中,选择运行仸务(Run manage.py Task)
此时会启动命令行窗口。
在命令行窗口中,我们输入“startapp MySite(App名称)”,回车之后即可完成应用的创建。
2.6 运行时Django的端口号默认用的8000的端口**
注意:有些Django项目,创建出来之后运行报错,提示没有os模块,这里只需要点开settings导入os模块即可
3、静态文件配置
- 由于我们的CSS、jQuery、JavaScript等都是Django来为我们调用的,所以我们要在settings中为他重新配置路径
- 1.先在项目创建一个static文件夹,与App同级。
- 2.然后在settings底部,加入下面这段代码:
# 配置静态文件
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
]
- 3.1 配置完成之后,就可以正常的在HTML模板中引入这些静态文件啦
4、路由配置
4.1 URL配置(URLconf):
-
就像Django所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表
-
你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。
urlpatterns = [
path('admin/', admin.site.urls),
path('timer/', views.timer), # views.timer(request)
# 简单的路由配置:路径 ---- 视图函数
re_path(r'^articles/2003/$', views.special_case_2003), # special_case_2003(request)
re_path(r'^articles/([0-9]{4})/$', views.year_archive), # year_archive(request, 2015)
# re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), # month_archive(request, year,month)
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), # month_archive(request, year,month)
# re_path(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
注意: 在这里,re_path ==> 2.0版本, path是最新版本(path支持2.0的语法,也有自己的新语法)
- 1、一旦匹配成功则不再继续
- 2、若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
- 3、不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
- 4、每个正则表达式前面的’r’ 是可选的但是建议加上。
示例:
/articles/2005/3/ 不匹配任何URL 模式,因为列表中的第三个模式要求月份应该是两个数字。
/articles/2003/ 将匹配列表中的第一个模式不是第二个,因为模式按顺序匹配,第一个会首先测试是否匹配。
/articles/2005/03/ 请求将匹配列表中的第三个模式。Django 将调用函数
views.month_archive(request, '2005', '03')
# 设置项是否开启URL访问地址后面不为/跳转至带有/的路径
APPEND_SLASH=True
4.2 无名分组和有名分组
-
1、上面的示例记得的使用了有名分组和无名分组的一些正则表达式组(通过圆括号)来捕获URL 中的值并以位置 参数传递给视图。在更高级的用法中,可以使用命名的正则表达式组来捕获URL中的值并以关键字 参数传递给视图。
-
2、在Python 正则表达式中,命名正则表达式组的语法是
(?P<name>pattern)
,其中name是组的名称,pattern是要匹配的模式。
from app01 import views
from django.conf.urls import url
urlpatterns = [
#无名分组
url(r'^article/\d{4}', views.year) ,
url(r'^article/(\d{4})$', views.year2),
# 如果有多个匹配一样的时候,谁放在上面就匹配谁,上面的就会把下面的覆盖了
# 正则加上括号,就是分组,会把分组的内容作为year2函数的参数传进去
url(r'^article/(\d{4})/(\d{2})$', views.year_month),
# 有名分组(就是给分组起个名字,这样定义的好处就是按照关键字参数去传参了,指名道姓的方式)
url(r'^article/(?P<year>\d{4})/(?P<month>\d{2})$', views.year_month_hasname)
]
注意: 捕获的值作为关键字参数而不是位置参数传递给视图函数。