接着上篇启动项目后,开始按Django的MVC框架开发新应用。
创建APP并注册
进入刚刚创建的项目目录,使用以下命令创建APP,命名为base:
python manage.py startapp base
进入workdesk\settings.py调整INSTALLED_APPS注册APP:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'base',
]
配置路由
为了是项目路由更清晰,我们在在APP目录增加路由映射文件urls.py,并在项目主路由增加引用项目路由的配置:
APP路由文件:
app_name = 'base' #这里是为了反向解析用
urlpatterns = [
#这里放映射的view
#path('admin/', admin.site.urls),
]
在项目urls.py里面增加对app路由的映射(引入include,urlpatterns里面增加一行路由)
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path(r'base/',include('base.urls')),#当匹配到base时,交由APP路由处理
]
创建模型(M)
两种方法创建模型:
1、先写models.py文件,再生成数据库表
本案例中,数据库后台需存储导出日志,包含序号、导出日期、文件名称三个字段,models.py文件如下:
from django.db import models
class AHistory(models.Model):
id = models.AutoField(db_column='ID', primary_key=True)
date = models.TimeField(blank=True, null=True)
filename = models.CharField(max_length=100, blank=True, null=True)
class Meta:
managed = False
db_table = 'a_history'
创建好models.py后,通过以下命令做数据库迁移生成数据库表:
python manage.py makemigrations
python manage.py migrate
前者是将model层转为迁移文件migration,后者将新版本的迁移文件执行,更新数据库。
这两中命令调用默认为全局,即对所有最新更改的model或迁移文件进行操作。如果想对部分app进行操作,就要在其后追加app name:
python manage.py makemigrations app_name
python manage.py migrate app_name
如果要精确到某个文件:
python manage.py migrate app_name filename.py
2、直接SQL文件创建数据库表,然后生成models.py文件
创建表的SQL语句,在数据库执行:
DROP TABLE IF EXISTS A_history;
CREATE table A_history
(
ID int NOT NULL COMMENT 'ID' primary key auto_increment ,
date time NULL COMMENT '导数时间',
filename varchar(100) NULL COMMENT '文件名称'
)
使用这条命令,会根据设置的数据库中的表在自动生成对应的Model代码,并打印出来:
python manage.py inspectdb
然后可以直接将打印的代码直接导入到指定的Model文件中,前提是创建了app(app)并且在setting.py文件中注册过
python manage.py inspectdb > app/models.py
配置了多个数据库,则还可以配置数据库别名来指定根据哪个库中的表来生成Model,default是默认的别名
将指定的表生成对应的Model
python manage.py inspectdb --database default >student/models.py
python manage.py inspectdb --database default table1 table2 >student/models.py
编写视图(V)
在APP目录的views.py里面,新增视图函数,以下示例为接收到请求后返回一段文字:
from django.shortcuts import render
from django.template import RequestContext
from django.http import HttpResponse #引入相应返回请求函数
# Create your views here.
#返回历史导出记录的视图
def showhistrys(request):
return HttpResponse('这是一个测试视图!')
编写完视图后,需要在APP路由里面增加路由配置:
from django.urls import path #引入路由函数path
from base.views import showhistrys #引入APP刚创建的视图函数
app_name = 'base' #这里是为了反向解析用
urlpatterns = [
path('', showhistrys), #路由指定路径返回的视图函数
]
启动服务,访问 http://127.0.0.1:8989/base 目录查看效果:
python manage.py runserver 8989
创建模板(C)
在APP目录下增加templates目录,在该目录下创建html页面(BI_getuser.html):
在项目settings.py增加模板相关配置,DIRS配置 成模板的目录:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, "templates")],
'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',
],
},
},
]
视图与模板关联显示动态页面
想要将视图与模板关联显示动态页面,需要调整视图函数返回数据,并且编写模板接收数据。
1、修改视图从模型获取数据
本案例我们定义一个histrys字典数据,并传递给BI_getuser.html模板,修改后APP视图函数Views.py如下:
from django.shortcuts import render #render函数是与模板交互传递数据的函数
from django.template import RequestContext
# Create your views here.
#返回历史导出记录的视图
def showhistrys(request):
#return HttpResponse('这是一个测试视图!')
histrys = {'date':'2020-04-14','name':'AAA'}
return render(request,'base/BI_getuser.html',histrys)
参考以下内容了解render函数的用法:
render方法
render方法用于将有关信息利用模板添加到要给用户发送的html文档中,render方法的参数:
- request:即视图函数中的HttpRequest对象,也就是第一个参数
- template_name:templates 中定义的文件,也就是html文档
- context: 要传入html文档中用于渲染呈现的数据, 默认是字典格式。也可以使用locals(),表示将函数中所有的变量传给模板
- content_type: 生成的文档要使用的MIME 类型。默认为DEFAULT_CONTENT_TYPE 设置的值
- status: http的响应代码,默认是200
- using: 用于加载模板使用的模板引擎的名称
例如:
def login(req): return render(req,"test.html",{"name":"sfencs"})
redirect方法
redirect方法表示重定向,参数可以一个完整的url路径如”https://www.cnblogs.com/"也可以是一个本网站的分支路径如"/login/“
这里有一点要注意,如果redirect的路径中写的是”login/“,即没有前面那一个“/”,那么会重定向到你当前页面的路径后再加上”login/“的那个路径。
redirect方法与render方法的区别在于redirect方法会重新走一遍重定向路径的视图函数的逻辑,render方法只是直接返回一个页面,上方的地址栏中的路径还是原来的路径。
2、修改html模板加入对应变量接收视图返回的数据
上述视图中返回的字典中包含date和name两个变量,我们修改html模板,包含该变量
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>导出BI企业微信已授权用户</title>
</head>
<body>
<h1>导出企业微信已授权用户</h1>
<p>
<button type="button">导出用户</button>
</p>
<dev>
{{date}} {{name}}
</dev>
</body>
</html>
浏览站点显示如下
关于模板的其他语法,可参考这篇文章 : [Django之模板] 。
视图与模型联动操作数据库
上述案例中,我们实现了视图将数据传递给模板生成动态网页,但是视图的数据是直接定义的,现实当中视图往往是通过模型操作数据库来增删改数据。
本案例将调整视图从已创建的模型中获取数据,修改APP的视图文件Views.py如下:
from django.shortcuts import render #render函数是与模板交互传递数据的函数
from .models import AHistory #导入需要的模型
from django.template import RequestContext
# Create your views here.
#返回历史导出记录的视图
def showhistrys(request):
#return HttpResponse('这是一个测试视图!')
histrys = AHistory.objects.all() #使用objects对象的all()函数获取数据库数据
return render(request=request,template_name = 'base\BI_getuser.html',context={'histrys':histrys})
其中,models.objects.all()可获取数据表所有数据,返回结果为一个可迭代对象,而rander的context参数必须是一个dict,因此给此可迭代对象一个key组成字典返回给页面。
由于histrys是一个可迭代对象,因此模板中需要使用循环将其迭代出来放到一个表格,修改模板html如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>导出BI企业微信已授权用户</title>
</head>
<body>
<h1>导出企业微信已授权用户</h1>
<p>
<button type="button">导出用户</button>
</p>
<dev>
<table border="1">
<tr>
<th>ID</th>
<th>文件名</th>
<th>导出日期</th>
<th>操作</th>
</tr>
{%for histry in histrys%}
<tr>
<td>{{histry.id}}</td>
<td>{{histry.filename}}</td>
<td>{{histry.date}}</td>
<td>编辑 删除</td>
</tr>
{%endfor%}
</table>
</dev>
</body>
</html>
刷新页面看到结果如下:
至此,我们完成了整个WEB开发的MVC部分。