Django学习第一步,入门教程
本文大部分内容来自刘江博客-Django2.1新手图文入门教程,所有代码全部经过本人手打,一些要注意的地方也已经标明。
开始学习 使用python进行web开发 ,做一个简单的记录。
一、web开发、web框架、html、css,js、Django、MCV/MTV简单介绍
- 首先,什么是Web开发?
那得先知道什么是web,web包括了客户端、服务器以及各种通讯协议。web简单的工作原理:客户端通过url向服务器发出请求资源的信息,服务器收到该信息后通过查询数据库找到该资源,并把该资源的副本打包成html形式发送给客户端。
Web开发指的是开发基于B/S架构,通过前后端的配合,将后台服务器的数据在浏览器上展现给前台用户的应用。比如将电子购物网站的商品数据在浏览器上展示给客户,在基于浏览器的学校系统管理平台上管理学生的数据,监控机房服务器的状态并将结果以图形化的形式展现出来等等。
2. 什么又是web框架呢?
Web框架: 别人已经设定好的一个Web网站模板,你学习它的规则,然后“填空”或“修改”成你自己需要的样子。
一般Web框架的架构是这样的:
其他基于python的web框架,如Tornado、Flask、Webpy都是在这个范围内进行增删裁剪的,如Tornado用的是自己的异步非阻塞通信协议,flask则只提供了最精简和基本的框架,Django直接使用WSFI通信协议,并实现了大部分web应用相关的功能。
3. Django简介
Django 是一个开放源代码的 Web 应用框架,由 Python 写成。Django本身基于MVC架构,即模型(Model)+视图(View)和模板(Template)设计模式,因此天然具有MVC的出色基因:开发快捷、部署方便、可重用性高、维护成本低等优点。
4. MVC与MTV模型
MVC 模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
通俗解释:一种代码和文件的组织和管理形式!其实就是把代码分散到不同的文件中,把不同类型的文件又放到不同目录下的一种做法,然后取了个高大上的名字。当然,它带来的好处有很多,比如前后端分离,松耦合等等,在使用中你慢慢体会就会逐渐明白它。
MVC 以一种插件式的、松耦合的方式连接在一起。
- 模型(M)- 编写程序应有的功能,负责业务对象与数据库的映射(ORM)。一般放在models.py文件中
- 视图(V)- 图形界面,负责与用户的交互(页面)。也就是HTML、CSS、JS等前端的东西
- 控制器(C)- 负责转发请求,对请求进行处理。定义业务逻辑相关,就是主要代码
MTV:Django 的 MTV 模式本质上和 MVC 是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django 的 MTV 分别是指:
- M 表示模型(Model):编写程序应有的功能,负责业务对象与数据库的映射(ORM)。
- T 表示模板 (Template):负责如何把页面(html)展示给用户。
- V 表示视图(View):负责业务逻辑,并在适当时候调用 Model和 Template。
除了以上三层之外,还需要一个 URL 分发器,它的作用是将一个个 URL 的页面请求分发给不同的 View 处理,View 再调用相应的 Model 和 Template,MTV 的响应模式如下所示:
解析:
用户通过浏览器向我们的服务器发起一个请求(request),这个请求会去访问视图函数:
- a.如果不涉及到数据调用,那么这个时候视图函数直接返回一个模板也就是一个网页给用户。
- b.如果涉及到数据调用,那么视图函数调用模型,模型去数据库查找数据,然后逐级返回。
视图函数把返回的数据填充到模板中空格中,最后返回网页给用户。
刘江博客中对MTV的介绍:目录分开,就必须有机制将他们在内里进行耦合。在Django中,典型的业务流程如下图所示:
5. html、css、js
html是一种文本标记语言。通俗点说,他是告诉浏览器数据应该以什么样的格式显示,以段落格式还是以标题形式,以图片形式还是以音频形式等等; 是静态网页,该文档本身只有页面结构,可以显示页面内容。
css是一种样式语言。css和html关联起来,我们就能看到一个符合人类正常审美的页面了。他就是为了让页面看起来不那么丑; 层叠样式表,通过设置对应的样式属性可以修改html文档内各元素的显示、位置等样式。
有了表示内容和结构的html,规定样式的css,他们组合起来只能得到一个静态的页面,没什么交互效果。例如当我们浏览淘宝网时,我们把鼠标指针放在衣服那一栏上,就会显示一个方框,方框里包含各种各样的信息。这就是js的作用。他可以实现用户和网页以及网页和服务器之间的数据交互。 Javascript,动态脚本语言,广泛应用于web应用的功能开发以及丰富页面体验,可以动态控制页面内容,如修改页面文字、图片、各种效果等。
一个通俗的例子:HTML就像人的身体,CSS就像人的衣服,Javascript就像人的思想和行为。
6. 还有一些名词
WSGI:Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为python语言定义的web服务器和web应用程序或框架之间的一种简单而通用的接口。
二、Django项目实例
- 程序安装
刘江博客中是用win+r,调出cmd,运行pip3 install django来安装的,但是我遇到了一些难以解决的问题,加上之前我一直使用anaconda,所以我就以管理员身份(不然会报错:没有权限)运行anaconda prompt,输入:conda install django,然后就安装成功了,也不需要设置环境变量,anaconda还是好用啊!
确认自己安装成功的方法。
import django
django.get_version()
print(django.get_version())
# 2.2.5
2. 创建Django项目 (下面所有操作都是在pycharm中进行滴)
文件->新项目-->Django
Django将自动生成下面的目录结构
与项目同名的mysite目录是项目核心文件。templates目录是HTML文件存放处(pycharm的安利),也就是MTV中的T。manage.py是Django项目管理文件。
3. 创建APP
每个Django项目中可以包含多个APP,相当于一个大型项目中的分系统、子模块、功能部件等等,相互之间比较独立,但也可以有联系。所有的APP共享项目资源。
在pycharm下方的Terminal终端中输入命令:
python manage.py startapp login
这样就创建了一个叫做loginAPP了,Django将自动生成login文件夹以及一系列文件:
4. 编写路由
路由是浏览器输入url,在Django服务器响应url的转发中心。路由都写在urls文件里,它将浏览器输入的url映射到相应的业务处理逻辑也就是视图。简单的urls编写方法如下图:
了解一下Django中的path()函数:
Django path() 可以接收四个参数,分别是两个必选参数:route、view 和两个可选参数:kwargs、name。
语法格式:
path(route, view, kwargs=None, name=None)
- route: 字符串,表示 URL 规则,与之匹配的 URL 会执行对应的第二个参数 view。
- view: 用于执行与正则表达式匹配的 URL 请求。
- kwargs: 视图使用的字典类型的参数。
- name: 用来反向获取 URL。
官方文档解释如下:
函数path()
具有四个参数,两个必须参数:route
和view
,两个可选参数:kwargs
和name
。现在,是时候来研究这些参数的含义了。
path()
参数:route
route
是一个匹配 URL 的准则(类似正则表达式)。当 Django 响应一个请求时,它会从urlpatterns
的第一项开始,按顺序依次匹配列表中的项,直到找到匹配的项。
这些准则不会匹配 GET 和 POST 参数或域名。例如,URLconf 在处理请求https://www.example.com/myapp/
时,它会尝试匹配myapp/
。处理请求https://www.example.com/myapp/?page=3
时,也只会尝试匹配myapp/
。
path()
参数:view
当 Django 找到了一个匹配的准则,就会调用这个特定的视图函数,并传入一个HttpRequest
对象作为第一个参数,被“捕获”的参数以关键字参数的形式传入。稍后,我们会给出一个例子。
path()
参数:kwargs
任意个关键字参数可以作为一个字典传递给目标视图函数。本教程中不会使用这一特性。
path()
参数:name
为你的 URL 取名能使你在 Django 的任意地方唯一地引用它,尤其是在模板中。这个有用的特性允许你只改一个文件就能全局地修改某个 URL 模式。
5. 编写视图函数
路由转发用户请求到视图函数。视图函数处理用户请求,也就是编写业务处理逻辑,一般都在views.py文件里。我们下面写一个简单的视图函数:
通过这两个步骤,我们将index这个url指向了views中的index()视图函数,它接收用户请求,并返回一个“Hello World!"字符串。
6. 运行web服务
现在我们就可以将web服务运行起来了。
运行之后,点击如图链接,自动跳转到浏览器程序界面。
修改url,添加“/index/”,就ok了。
可以看到,Hello World!字符串,至此,一个最简单的Django编写的Web服务就启动成功啦!
7. 返回HTML文件
我们实际访问网页时想要的肯定不只是一个字符串,通过我们是将HTML文件返回给用户。
下面,我们在templates目录中新建一个index.html文件:
代码如下:
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>test</title>
</head>
<h1 style="background-color:antiquewhite;color:black">Hellow World!</h1>
</body>
</html>
此时,如果按alt+F2,在浏览器中查看,效果是这样的
再修改一下views文件:
为了让Django知道我们的html文件在哪里,需要修改settings文件中的相应内容。但默认情况下,它正好适用,无需修改。
接下来,我们刷新浏览器或者重启Web服务器,看到带有样式的"Hello World!"。
注:这里有个小技巧,在多次频繁重启服务时,由于端口未释放的原因,容易启动不了服务,修改一下端口就OK了。
8. 适用静态文件
我们已经可以将HTML文件返还给用户了,但是这还不够,前端三大块HTML、CSS、JavaScript,还有各种插件,它们齐全才是一个完整的页面。在Django中,一般将这些静态文件放在static目录中。
接下来,在mysite中新建一个static目录,我们的css、js和各种插件都可以放在这个目录里面。我们在static目录下再新建一个js目录,然后拷贝了一个jquery-3.2.1.min.js进来。(这好像是jquery的库,jquery是开源的JavaScript框架~,我在网上找到了这个资源,然后复制了进来)
为了让Django知道这个static目录的存在,并且能够找到这个目录,需要对settings进行配置:
https:// docs.djangoproject.com/ en/2.2/howto/static-files/ 介绍如何为静态文件提供服务
现在,我们就可以在index.html中引入js文件了:
这个黑白块我不知道它是个什么作用。
现在刷新浏览器,查看结果,还不会任何变化,因为仅仅只是引入了一个jquery而已。
9. 接收用户发送的数据
前面,我们将一个要素齐全的HTML文件返还给了用户浏览器。但这还不够,因为Web服务器和用户之间没有动态交互。
下面我们来设计一个表单,让用户输入用户名和密码,提交给index这个url,服务器将会接收到这些数据。
先修改index.html文件,删除原先的内容,写入下面的内容:
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>首页</title>
</head>
<h1>用户输入:</h1>
<form action="/index/" method="post">
用户名:<input type="text" name="username" /><br />
密码:<input type="password" name="password" /><br />
<input type="submit" value="提交" />
</form>
</body>
</html>
刷新浏览器,界面如下图所示:
这时候,我们先不要往输入框输入信息,要先修改login目录下views.py文件内容为:
from django.shortcuts import render
from django.shortcuts import HttpResponse
# Create your views here.
def index(request):
if request.method == "POST":
username = request.POST.get("username")
password = request.POST.get("password")
print(username,password)
#return HttpResponse('Hello World!')
return render(request,'index.html')
刷新浏览器,随便输入些内容提交,结果出现了下面的403界面:
这是因为Django有一个跨站请求保护机制,需要我们在index.html文件中加入一行
{% csrf_token %}。
再次刷新浏览器,输入信息 ,这次就可以成功提交了,然后我们可以在pycharm的terminal看到输出语句打印出来的数据了。
一定注意是终端,终端,终端! 终端处查看,我在运行结果处观察了半天,还想着哪里写错了,检查了好几遍,突然灵光一现,点了一下终端,发现用户信息原来是在这里输出了。
10. 返回动态页面
now,我们接受到了用户的数据,但返回给用户的依然是个静态页面,通常我们会根据用户的数据,进行处理后再返回给用户。
先修改views.py文件内容:
from django.shortcuts import render
from django.shortcuts import HttpResponse
# Create your views here.
user_list = []
def index(request):
if request.method == "POST":
username = request.POST.get("username")
password = request.POST.get("password")
print(username, password)
temp = {'user':username,'pwd':password}
user_list.append(temp)
#return HttpResponse('Hello World!')
return render(request, 'index.html',{'data':user_list})
再修改index.html文件:
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>首页</title>
</head>
<h1>用户输入:</h1>
<form action="/index/" method="post">
{% csrf_token %} <!--加入这行 -->
用户名:<input type="text" name="username" /><br />
密码:<input type="password" name="password" /><br />
<input type="submit" value="提交" />
</form>
<h1>用户展示:</h1>
<table border = "1">
<thead>
<tr>用户名</tr>
<tr>密码</tr>
</thead>
<tbody>
{% for item in data %}
<td>{{ item.user }}</td>
<td>{{ item.pwd }}</td>
{% endfor %}
</tbody>
</table>
</body>
</html>
notice:Django采用自己的模板语言,根据提供的数据,替换掉HTML中的相应部分,详细语法入门后再深入学习。
then,刷新浏览器,多输入几次。
we can see,我们获得了用户实时输入的数据,并将它实时展示在了用户页面上,这是个不错的交互过程。在pycharm中,我们也可以看到每次输入的数据。
11. 使用数据库
流程走到这里,django的MTV框架基本已经浮出水面了,只剩下最后的数据库部分了。
上面我们虽然和用户交互得很好,但并没有保存任何数据,页面一旦关闭,或服务器重启,一切都将回到原始状态。
使用数据库的需求是毫无疑问的,Django通过自带的ORM框架操作数据库,并且原生支持轻量级的sqlite3数据库。下面我们来看一看:
使用数据库前,我们需要注册app:
不注册它,数据库就不知道该给哪个app创建表。
然后我们在settings中,配置数据库相关的参数,如果使用sqlite3,则不需要做任何修改。
再编辑models.py文件,即MTV中的M。
from django.db import models
# Create your models here.
class UserInfo(models.Model):
user = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
我们创建了两个字段,分别保存用户名和密码。
接下来要在pycharm的Terminal中通过命令来创建数据库的表了,有两条命令,分别是:
python manage.py makemigrations
这会在login目录中的migrations目录中生成一个0001_initial.py 迁移记录文件 。
再输入命令:
python manage.py migrate
这样,我们就在数据库中将所有app的数据表都创建好了,可以看到项目根目录下出现了一个db.sqlite3文件:
现在,我们来修改views.py中的业务逻辑
from django.shortcuts import render
from django.shortcuts import HttpResponse
from login import models
# Create your views here.
#user_list = []
def index(request):
if request.method == "POST":
username = request.POST.get("username")
password = request.POST.get("password")
#print(username, password)
#temp = {'user':username,'pwd':password}
#user_list.append(temp)
# 将数据保存到数据库