a、Django简介
Django
参照2020版Python教程_完全入门_学完达到Python工程师水平【千锋】~持续更新中、刘江的博客教程和自强学堂的文档
一、Django简介
1. web框架介绍
Django是基于Python的Web开发框架。Django 中提供了开发网站经常用到的模块,常见的代码都为你写好了,通过减少重复的代码,Django 使你能够专注于 web 应用上有趣的关键性的东西。为了达到这个目标,Django 提供了通用Web开发模式的高度抽象,提供了频繁进行的编程作业的快速解决方法,以及为“如何解决问题”提供了清晰明了的约定。Django的理念是DRY(Don't Repeat Yourself)来鼓励快速开发!
Web框架: 别人已经设定好的一个Web网站模板,你学习它的规则,然后“填空”或“修改”成你自己需要的样子。
一般Web框架的架构是这样的:
其它基于Python的Web框架,如Tornado、Flask、Webpy都是在这个范围内进行增删裁剪的。例如Tornado用的是自己的异步非阻塞通信协议,Flask则只提供了最精简和基本的框架,Django直接使用WSGI通信协议,并实现了大部分Web应用相关的功能。
2. MVC/MTV介绍
MVC:
百度百科:全名Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件工程典范,用业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
通俗解释:一种代码和文件的组织和管理形式!不要被缩写吓到了,这其实就是把代码分散到不同的文件中,把不同类型的文件又放到不同目录下的一种做法,然后取了个高大上的名字。当然,它带来的好处有很多,比如前后端分离,松耦合等等,在使用中你慢慢体会就会逐渐明白它。
其中:
- 模型(model):定义数据库相关的内容,一般放在models.py文件中。
- 视图(view):定义HTML等静态网页文件相关,也就是那些HTML、CSS、JS等前端的东西。
- 控制器(controller):定义业务逻辑相关,就是你的主要代码。
MTV:
Django觉得MVC的字面意思很别扭,不太符合它的理念,就给它改了一下。view不再是HTML相关,而是主业务逻辑V了,相当于控制器。HTML被放在Templates中,称作模板T,于是MVC就变成了MTV。这其实就是一个文字游戏,和MVC本质上是一样的,换了个名字和叫法而已,换汤不换药。
3. Django的MTV模型组织
目录分开,就必须有机制将他们在内里进行耦合。在Django中,典型的业务流程如下图所示:
二、Django项目实例
1. 程序安装
Django各版本对Python版本的依赖关系如下表所示:
Django 版本 | Python 版本 |
---|---|
1.11 | 2.7, 3.4, 3.5, 3.6, 3.7 (1.11.17 添加) |
2.0 | 3.4,3.5,3.6,3.7 |
2.1 | 3.5,3.6,3.7 |
2.2 | 3.5, 3.6, 3.7, 3.8 (2.2.8 添加) |
3.0 | 3.6, 3.7, 3.8 |
3.1 | 3.6, 3.7, 3.8 |
Django本身的版本规划时间图如下所示:
Python3.7、pip3及Pycharm请自行安装。
(1)安装Django:
这里只介绍较为简单的pip3命令安装方式。
win+r
,调出cmd,运行命令pip3 install django
,自动安装Pypi提供的最新版本。
注意:
- 建议升级一下pip3,命令
python -m pip install --upgrade pip
- 如果你以前安装过django,则会使用先前缓存的安装文件
- 使用cmd,请以管理员身份运行,否则可能出现权限问题
运行django-admin help
,能看到下面的内容表示安装过程OK。
或者进入Python交互式环境(注意一定要进入刚才安装了Django的Python解释器),按下面所示查看安装版本:
python
>>> import django
>>> django.get_version()
2.2
再或者使用pip list
命令,查看是否存在Django模块。
2. 创建Django项目
在Linux等命令行界面下,使用Django提供的命令和vim也能进行项目开发。但是这里推荐使用Pycharm这个目前最好的Python开发IDE,它功能强大,界面友好。(下面所有的操作都在Pycharm中进行。)
点击file-->new project
,出现下面的对话框。
- 在Location处选择工程目录
- 在
使用此项目新建环境
处选择Virtualenv(这可能需要你提前使用pip install virtualenv
命令安装虚拟工具virtualenv)。通常情况下,虚拟环境会以venv的名字,自动在工程目录下生成。 - 在Base interpreter处,选择你要使用的Python解释器
- 两个单选框,根据需要自行选择。引入全局设置包、为所有的项目引入可用的
- 如果想使用现成的解释器或者虚拟环境,请选择
Existing interpreter
再点开下方的More Settings
:
- Template language: 选择使用的模板语言,默认Django就行。
- Templates folder:这是Pycharm安利给我们的功能,用于额外创建一个工程级别的模板文件的保存目录,可以不设置,让它空着。
template
是目录的名字,可换成任何你喜欢的名字。这里我们不选择,因为可能出现os模块缺少的bug。 - Application name: 自动帮你创建一个app,可选的功能
- Enable Django admin: 用于开启后台管理admin功能,一般勾上。
没什么问题了,就点击Create吧。
在新弹出的弹窗中选择open in current window
,在当前窗口打开。
或使用:
#命令:django-admin.py startproject project_name
#或: django-admin startproject project_name
django-admin startproject mysite
Django将自动生成下面的目录结构:
与项目同名的mysite目录中是项目核心文件。templates目录是HTML文件存放处(这是Pycharm安利给我们的),也就是MTV中的T。manage.py
是Django项目管理文件。
用tree /f
可以查看项目目录结构:
├── mysite #项目包
│ ├── __init__.py #包标志
│ ├── settings.py #主配置
│ ├── urls.py #主路由
│ └── wsgi.py #网关(wsgi)接口
└── manage.py #项目管理
项目配置文件(settings.py):
#项目根目录,即manage.py所在的目录
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
#用于保护项目的加密盐
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '8%7+*)mssqrog5x+*94s0&)kc%ssv!wcyo&px3js!!3z7x)gvp'
#调试模式
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
#允许访问的主机,如果要让远程客户端连接需要修改配置文件,其中0.0.0.0:9000是可选的,0.0.0.0说明任何ip都可以访问。
ALLOWED_HOSTS = []
#安装应用
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
#中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
#根路由
ROOT_URLCONF = 'mysite.urls'
#模块配置
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],#模板路径
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
#使用的WSGI应用程序对象的完整Python路径
WSGI_APPLICATION = 'mysite.wsgi.application'
#数据库配置
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# 可插入的密码验证
# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# 国际化
# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/
#语言,中文是zh-hans
LANGUAGE_CODE = 'en-us'
#时区,中国是Asia/Shanghai
TIME_ZONE = 'UTC'
#国际化I18N
USE_I18N = True
#区域设置指定的格式是否具有更高的优先级
USE_L10N = True
#系统时区
USE_TZ = True
#静态文件路径
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATIC_URL = '/static/'
测试服务器启动,在命令行下输入
#命令:python manage.py runserver [ip:port]
python manage.py runserver
python manage.py runserver 0.0.0.0:9000
测试服务器默认端口是8000,仅限于本地链接,打开浏览器输入:
http://localhost:8000 #或者
http://127.0.0.1:8000
3. 创建APP
在每个Django项目中可以包含多个APP,相当于一个大型项目中的分系统、子模块、功能部件等等,相互之间比较独立,但也可以有联系。所有的APP共享项目资源。
在Pycharm下方的Terminal终端中输入命令:
#命令:python manage.py startapp app_name
或 django-admin.py startapp app_name
python manage.py startapp login
这样就创建了一个叫做login的APP,django自动生成“login”文件夹,及一系列文件:
创建应用后,项目结构如下:
├── login #应用
│ ├── admin.py #站点管理
│ ├── apps.py #应用程序自身信息
│ ├── __init__.py #包标志
│ ├── migrations #迁移文件
│ │ └── __init__.py #包标志
│ ├── models.py #模型
│ ├── tests.py #测试文件
│ └── views.py #视图响应文件
├── db.sqlite3 #sqlite数据库
├── mysite 项目
│ ├── doc.py
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-37.pyc
│ │ ├── settings.cpython-37.pyc
│ │ ├── urls.cpython-37.pyc
│ │ └── wsgi.cpython-37.pyc
│ ├── settings.py #系统配置
│ ├── urls.py #主路由
│ └── wsgi.py #网关(wsgi)接口
└── manage.py #项目管理
4. 编写路由
路由是浏览器输入url,在Django服务器响应url的转发中心。路由都写在urls文件里,它将浏览器输入的url映射到相应的业务处理逻辑也就是视图。简单的urls编写方法如下图:
5. 编写视图函数
路由转发用户请求到视图函数。视图函数处理用户请求,也就是编写业务处理逻辑,一般都在views.py
文件里。我们下面写一个简单的视图函数:
通过上面两个步骤,我们将index
这个url指向了views里的index()
视图函数,它接收用户请求,并返回一个“hello world”字符串。
6. 运行web服务
现在我们已经可以将web服务运行起来了。
命令行的方式是:
python manage.py runserver 127.0.0.1:8000
但在Pycharm中,你可以这么干,在上部工具栏中找到下面图示的图标。
点击下拉箭头:
点击edit configurations
:
在host中填入127.0.0.1
,port中填入8000。
OK确定之后,点击绿色的三角,web服务就运行起来了。
然后按下图所示点击链接:
自动跳转到浏览器程序界面。显示的却是下图的404页面:
修改一下url,添加“/index/”,就一切ok了!
可以看到我们的'Hello World!'欢迎词了!
至此,一个最简单的Django编写的web服务就启动成功了。
7. 返回HTML文件
上面我们返回给用户浏览器的是什么?一个字符串!实际上这肯定不行,通常我们都是将HTML文件返回给用户。
下面,我们在templates目录中新建一个index.html
文件:
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
<h1 style="background-color: antiquewhite;color: black">Hello World!</h1>
</body>
</html>
再修改一下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
进来:
为了让Django知道这个static目录的存在,并能够找到这个目录,需要对settings进行配置:
现在,我们就可以在index.html
中引入js文件了:
重新启动web服务,刷新浏览器,查看结果。当然,你啥都看不出来,因为仅仅引入了一个jqurey而已。
9. 接收用户发送的数据
前面,我们将一个要素齐全的HTML文件返还给了用户浏览器。但这还不够,因为web服务器和用户之间没有动态交互。
下面我们设计一个表单,让用户输入用户名和密码,提交给index这个url,服务器将接收到这些数据。
先修改index.html
文件。删除原来的内容,写入下面的内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<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>
重启web服务,刷新页面,如下图所示:
这时候我们先不要往输入框内输入信息。我们先修改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 render(request, 'index.html')
重启web服务,刷新index页面,然后我们随便输入点什么东西,点击提交,结果出现了下面的403页面。
这是因为django有一个跨站请求保护机制,这需要我们在index.html
文件中加入一行{% csrf_token %}
。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<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>
</body>
</html>
再次进入浏览器,刷新index页面,输入点东西,这次就能成功提交了,然后我们在Pycharm中可以看到print语句打印出来的相应数据了。
10. 返回动态页面
现在,我们收到了用户的数据,但返回给用户的依然是个静态页面。通常我们会根据用户的数据,进行处理后再返回给用户。
先改造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 render(request, 'index.html', {'data': user_list})
再改造index.HTML
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<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 %}
<tr>
<td>{{ item.user }}</td>
<td>{{ item.pwd }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
说明:Django采用自己的模板语言,类似jinja2,根据提供的数据,替换掉HTML中的相应部分,详细语法入门后再深入学习。
接下来,重启服务,刷新浏览器,多输入几次。
可以看到,我们获得了用户实时输入的数据,并将它实时展示在了用户页面上,这是个不错的交互过程。在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)
这里我们创建了2个字段,分别保存用户的名字和密码。
接下来要在Pycharm的Teminal中通过命令创建数据库的表了。有2条命令,分别是:
python manage.py makemigrations
这会在login目录中的migrations目录中生成一个0001_initial.py
迁移记录文件。
再输入命令:
python manage.py migrate
运行结果如下:
D:\work\for_test\mysite>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, login, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying login.0001_initial... OK
Applying sessions.0001_initial... OK
这样,我们就在数据库中将所有app的数据表都创建好了。我们可以看到项目根目录下出现了一个db.sqlite3
文件:
现在,我们来修改views.py中的业务逻辑
from django.shortcuts import render
from login import models # 导入models文件
# Create your views here.
def index(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
# 将数据保存到数据库
models.UserInfo.objects.create(user=username, pwd=password)
# 从数据库中读取所有数据,注意缩进
user_list = models.UserInfo.objects.all()
return render(request, 'index.html', {'data': user_list})
重启web服务后,刷新浏览器页面,之后和用户交互的数据都能保存到数据库中。任何时候都可以从数据库中读取数据,展示到页面上,不会因为服务器中途关闭,丢失先前的数据了。
至此,一个要素齐全,主体框架展示清晰的Django项目完成了。
三、 Django使用总结
Django作为Python必学Web框架,它的功能强大,内容全面,但同时也意味着限制颇多,灵活性低,可修改性差,这就是鱼和熊掌不可兼得了。我们学习Django,其实就是在学习一个软件,首先要理解它的基本原理,把握它的整体框架,牢记一些基本规则,剩下的就是不断深入细节,然后熟能生巧、经验多少的问题了,不存在多高深的不可掌握的技术。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)