Django MVC概述和开发流程

2022-11-15 21:10:56 浏览数 (1)

在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中定义模型类如下:

代码语言:javascript复制
# 学校模型类
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
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的命令:

代码语言:javascript复制
python manage.py shell

首先引入模型类

代码语言:javascript复制
from school_test.models import SchoolInfo, StudentInfo

查询所有学校信息:

SchoolInfo.objects.all()

返回一个所有记录组成的列表

新建学校对象然后插入几条数据:

代码语言:javascript复制
sc1 = SchoolInfo()
sc1.name = '北京大学'
sc1.addr = '北京'
sc1.save()   # save后才会生效

sc2 = SchoolInfo()
sc2.name = '清华大学'
sc2.addr = '北京'
sc2.save()

查找学校:

代码语言:javascript复制
sc3 = SchoolInfo.objects.get(name='北京大学')
# 可以直接通过修改这个实例的属性进行数据库的CURD
sc3.id  # 打印id
sc3.name = '浙江大学'
sc3.addr = '浙江'
sc3.save()

删除学校

代码语言:javascript复制
s2.delete()

对象的关联操作,新建学生对象然后插入几条数据:

代码语言:javascript复制
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()

学校和学生是一对多的关系,django中提供了关联的操作方式。为了便于阐述,把学校称为一类,学生称为多类。在多类记录中访问一类直接使用st2.school即可,而在一类记录中访问多类可以使用

代码语言:javascript复制
# 一类.多类名小写_set.all()  返回的是多类实例对象组成的列表
sc3.studentinfo_set.all()

视图(View)

1.定义视图函数

视图函数是Django用来处理HTTP请求的Python函数。在应用下的views.py定义一个视图函数,直接返回一个HttpResponse对象

代码语言:javascript复制
from django.http import HttpResponse

def index(request):
    return HttpResponse("hello world")

2.配置URL映射

URL映射配置可以看做是Django项目的入口配置。用户在浏览器地址栏中输入url,请求到网站后,获取url信息,然后与编写好的urlpatterns列表项逐条匹配,如果匹配成功则调用对应的视图函数,如果所有的URLconf都没有匹配成功,则返回404错误。

在应用下创建urls.py文件,定义urlpatterns列表。该列表项为一个django.conf.urls.url实例,urls函数的第一个参数为正则表达式,用来匹配url,第二个参数是该url被映射到的视图函数名。创建的内容如下:

代码语言:javascript复制
from django.conf.urls import url
from school_test import views

urlpatterns = [
    url(r'^index$', views.index),
]

然后将该应用的url映射包含到全局项目中,打开与Django项目同名的子目录下的urls.py中为urlpatterns添加一个列表项,如下:

代码语言:javascript复制
urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^', include('school_test.urls')),
]

视图和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中加入

代码语言:javascript复制
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',
            ],
        },
    },
]

2.编写模板文件

打开刚才创建的index.html文件,在其中加入以下内容

代码语言:javascript复制
<!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>

用花括号{}包含的内容均为模板文件的特殊语法。

代码语言:javascript复制
{# 注释 #}

表示注释,不会出现在最终渲染出来的html文件中;

代码语言:javascript复制
{{ 变量名 }}

表示在模板中使用变量,变量可以是从视图函数中传递过来的,也可以是在模板中定义的;

代码语言:javascript复制
{% 代码段 %}

表示在模板中编写的代码段。

3.在视图中调用模板

调用模板分为三部:

  • 1.加载模板
  • 2.构造上下文
  • 3.渲染模板,并返回http响应

修改之前在应用下的views.py定义的视图函数

代码语言:javascript复制
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))

以上的三步代码,Django框架做了一个封装,提供了render函数,使用起来更为简洁。render函数第一个参数为request对象,第二个参数为模板文件路径,第三个参数为上下文(字典,向模板文件传递的数据)

代码语言:javascript复制
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)

打开浏览器刷新页面,发现模板文件加载了,而且内容也被替换了

本文作者: Ifan Tsai  (菜菜)

本文链接: https://cloud.tencent.com/developer/article/2164568

版权声明: 本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!

0 人点赞