在Django环境搭建和开发初体验中已经讲解了Django环境的搭建和Django自带服务器的运行。
MVC架构
**MVC(Model View Controller)**模式最早由Trygve Reenskaug在施乐帕克研究中心提出,在20世纪80年代作为Smalltalk编程语言的一种软件内部架构。后来MVC设计模式被其他语言所借鉴,成为软件工程领域重要的一种软件架构模式。采用将业务逻辑、数据、界面显示分离的方法组织代码,核心思想就是解耦。MVC将Web应用分为三个部分:
- 模型(Model) 用于封装与应用程序业务逻辑相关的数据处理,是应用程序中用于处理数据逻辑的部分,通常负责对数据库的操作。
- 视图(View) 负责数据的显示和呈现,通常视图是依据模型数据创建的,MVC中的一个Model通常为多个View提供服务。
- 控制器(Controller) 负责从用户获取输入,是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
这三层分离,分工合作,使得在改进和升级界面及用户交互流程时,不需要重写业务逻辑和数据操作代码。MVC架构图下图所示。
MVT架构
Django同样采用的是MVC设计模式,只是在Django中被称为**MVT(Model View Template)架构。在MVT中视图(View)代替了MVC中的控制器(Controller),而模板(Template)则相当于MVC中的视图(View)**。其本质思想跟MVC毫无区别。MVT架构图如下图所示。
模型(Model)
ORM
**ORM(Object-Relational Mapping, 对象关系映射)**的作用是在关系型数据库和业务逻辑之间做一个映射,这样使得开发者在操作数据库的时候,就不再需要使用sql语句了,只需要采用面向对象的方式来操作数据库。在Django中,ORM在开发者和数据库之间建立了一个中间层,把对数据库的CURD转换成了Python中的对象实体的操作,这样既屏蔽了不同数据库之间的差异,而且又使得开发者可以使用面向对象的特性来操作数据库。
在Django中进行数据库开发一般需要三个步骤:
- 1.在应用的models.py中定义模型类
- 2.迁移
- 3.通过类和对象完成对数据库的CURD
1.定义模型类
首先添加了一个school_test应用,为school_test应用设计学校类和学生类
注:不需要定义主键,Django在迁移时会自动生成主键,并且值为自动增长
设计学校类
学校类:
- 类名:SchoolInfo
- 学校名:name
- 学校地点:addr
设计学生类
学生类:
- 类名:StudentInfo
- 姓名:name
- 年龄:age
- 性别:gender
- 学校:school
注:学校和学生是一对多的关系,所以学生类中的学校正是体现这个关系
模型类需要继承自models.Model,根据设计,在models.py中定义模型类如下:
<code style="margin-left:0"># 学校模型类 class SchoolInfo(models.Model): name = models.CharField(max_length=20) addr = models.CharField(max_length=100) # 用来说明对象的字符表达方式, # 如果在Python 2中,重写的是__unicode__方法 def __str__(self): return self.name # 学生模型类 class StudentInfo(models.Model): name = models.CharField(max_length=20) age = models.IntegerField() gender = models.BooleanField(default=True) # 外键,建立学校和学生的一对多关系 school = models.ForeignKey(SchoolInfo) def __str__(self): return self.name</code>
2.迁移
迁移分为两步:
- 1.生成迁移文件:
python manage.py makemigrations
- 2.执行迁移:
python manage.py migrate
1.生成迁移文件
执行后会在应用目录下的migrations目录下生成迁移文件,如下图所示
打开上图中的迁移文件如下图,可以看到自动添加了主键id并且为自动增长
2.执行迁移
执行完后会在根目录下生成数据库文件,Django默认采用sqlite3数据库。数据库中表的命名为应用命_模型类名,而且在模型类中添加了外键则会生成命名为外键模型类名_id的外键字段。
3.数据库操作
完成数据表的迁移之后,下面就可以通过进入项目的shell,进行简单的API操作。如果需要退出项目,可以使用ctrl+d快捷键或输入quit()。
进入项目shell的命令:
<code style="margin-left:0">python manage.py shell</code>
首先引入模型类
<code style="margin-left:0">from school_test.models import SchoolInfo, StudentInfo</code>
查询所有学校信息:SchoolInfo.objects.all()
返回一个所有记录组成的列表
新建学校对象然后插入几条数据:
<code style="margin-left:0">sc1 = SchoolInfo() sc1.name = '北京大学' sc1.addr = '北京' sc1.save() # save后才会生效 sc2 = SchoolInfo() sc2.name = '清华大学' sc2.addr = '北京' sc2.save()</code>
查找学校:
<code style="margin-left:0">sc3 = SchoolInfo.objects.get(name='北京大学') # 可以直接通过修改这个实例的属性进行数据库的CURD sc3.id # 打印id sc3.name = '浙江大学' sc3.addr = '浙江' sc3.save()</code>
删除学校
<code style="margin-left:0">s2.delete()</code>
对象的关联操作,新建学生对象然后插入几条数据:
<code style="margin-left:0">st1 = StudentInfo() st1.name = '张三' st1.age = 18 st1.gender = True # 直接赋值外键模型类对应的实例对象 st1.school = sc3 st1.save() st2 = StudentInfo() st2.name = '李四' st2.age = 18 st2.gender = False st2.school = sc3 st2.save()</code>
学校和学生是一对多的关系,django中提供了关联的操作方式。为了便于阐述,把学校称为一类,学生称为多类。在多类记录中访问一类直接使用st2.school
即可,而在一类记录中访问多类可以使用
<code style="margin-left:0"># 一类.多类名小写_set.all() 返回的是多类实例对象组成的列表 sc3.studentinfo_set.all()</code>
视图(View)
1.定义视图函数
视图函数是Django用来处理HTTP请求的Python函数。在应用下的views.py定义一个视图函数,直接返回一个HttpResponse对象
<code style="margin-left:0">from django.http import HttpResponse def index(request): return HttpResponse("hello world")</code>
2.配置URL映射
URL映射配置可以看做是Django项目的入口配置。用户在浏览器地址栏中输入url,请求到网站后,获取url信息,然后与编写好的urlpatterns列表项逐条匹配,如果匹配成功则调用对应的视图函数,如果所有的URLconf都没有匹配成功,则返回404错误。
在应用下创建urls.py文件,定义urlpatterns列表。该列表项为一个django.conf.urls.url实例,urls函数的第一个参数为正则表达式,用来匹配url,第二个参数是该url被映射到的视图函数名。创建的内容如下:
<code style="margin-left:0">from django.conf.urls import url from school_test import views urlpatterns = [ url(r'^index$', views.index), ]</code>
然后将该应用的url映射包含到全局项目中,打开与Django项目同名的子目录下的urls.py中为urlpatterns添加一个列表项,如下:
<code style="margin-left:0">urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^', include('school_test.urls')), ]</code>
视图和URL都配置好了,python manage.py runserver
运行Django项目候,在浏览器中输入http://127.0.0.1:8000/index
,成功看到视图函数被执行了
模板(Template)
在上面视图的讲解中,只是简简单单返回了一个纯文本hello world的HttpResponse对象,而实际中需要用到html、css等渲染和js的加载,所以需要使用模板文件来解决这个问题。模板文件是一种文本文件,主要由html、css等组成,但是除此之外Django模板文件支持特殊的模板语法用于动态替换内容。
1.创建模板文件
在Django项目根目录下创建templates目录,之后会在这个目录下创建若干个目录供各个应用使用,所以在该目录下创建与应用同名的目录,然后再创建index.html,创建完后目录结构如下图所示
设置Django项目的模板路径,打开与Django项目同名的子目录下的settings.py,在TEMPLATES中加入
<code style="margin-left:0">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', ], }, }, ]</code>
2.编写模板文件
打开刚才创建的index.html文件,在其中加入以下内容
<code style="margin-left:0"><!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <h2>学校如下:</h2> <ul> {# 遍历学校 #} {% for sc in schools %} <li>{{ sc.name }}</li> {% endfor %} </ul> </body> </html></code>
用花括号{}包含的内容均为模板文件的特殊语法。
<code style="margin-left:0">{# 注释 #}</code>
表示注释,不会出现在最终渲染出来的html文件中;
<code style="margin-left:0">{{ 变量名 }}</code>
表示在模板中使用变量,变量可以是从视图函数中传递过来的,也可以是在模板中定义的;
<code style="margin-left:0">{% 代码段 %}</code>
表示在模板中编写的代码段。
3.在视图中调用模板
调用模板分为三部:
- 1.加载模板
- 2.构造上下文
- 3.渲染模板,并返回http响应
修改之前在应用下的views.py定义的视图函数
<code style="margin-left:0">from django.http import HttpResponse from school_test.models import SchoolInfo, StudentInfo def index(request): # 从数据库中查询所有学校信息 schools = SchoolInfo.objects.all() # 1.加载模板 template = loader.get_template('school_test/index.html') # 2.构造上下文 context = RequestContext(request, { 'schools': schools }) # 3.渲染模板,并返回http响应 return HttpResponse(template.render(context))</code>
以上的三步代码,Django框架做了一个封装,提供了render函数,使用起来更为简洁。render函数第一个参数为request对象,第二个参数为模板文件路径,第三个参数为上下文(字典,向模板文件传递的数据)
<code style="margin-left:0">from django.shortcuts import render from school_test.models import SchoolInfo, StudentInfo def index(request): # 从数据库中查询所有学校信息 schools = SchoolInfo.objects.all() context = { 'schools': schools } return render(request, 'school_test/index.html', context)</code>
打开浏览器刷新页面,发现模板文件加载了,而且内容也被替换了
本文作者: Ifan Tsai (菜菜)
本文链接: https://www.caiyifan.cn/p/eea351d6.html
版权声明: 本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!
未经允许不得转载:木盒主机 » Django MVC概述和开发流程