如何用 Python 快速开发一个网站

Python 用来开发网站的框架很多,本次 Chat 选用 Django 来带大家开发一个简单的网站。网站开发需要掌握的知识比较多,但是我们是用开源框架可以大大减少我们的工作量,对底层实现原理也不需要完全了解。

一、开发环境的搭建

Django 是 Python 用来开发 Web 应用程序的一个框架,采用的 MTV 模式,实际上 MTV 模式和 MVC 模式没有本质的区别,MTV 只是 MVC 的一个衍生。

MVC(Model View Controller)是指模型、视图和控制层,在该模式下三层是分离的,我们通过视图层向用户展示数据,用户进行操作后通过控制层执行逻辑操作,最后使用模型层修改数据库中的数据。而 MTV(Model Tempalte View)和 MVC 是一样的,在 MTV 中分为模型、模板和视图层。这里的视图层相当于 MVC 中的控制层(Controller),而模板层则相当于 MVC 中的 View。

1.1 Python 环境安装

安装 Django 的前提就是有 Python 环境,我们先安装 Python 环境。进入官网下载相应版本,这里选取 Python 3.7:


版本可以自行选择,但是不推荐 2.x 坂本。我们只需要打开文件安装就可以了。在安装过程中,我们勾选 add to path 就不需要自己配置环境变量了。

1.2 Django 安装

因为 Django 版本不同语法方面也有一些差异,所以我们要先确定使用哪个版本。如下图:

我们可以直接使用 pip 安装:

pip install django==2.2

安装完成后我们就可以开始使用 Django 了。

1.3 运行项目

HelloWorld 是我们最基本的案例了,我们来试试开发一个最简单的 Django 项目。我们在安装 Django 后,可以在 Python 的安装目录下 /Script 文件夹下发现 django-admin.exe 程序,这个程序的作用就是开启 Django 项目。我们在 Script 目录下打开命令行。如图,红框内输入 cmd:

python django网页开发工具 python网站开发入门_django


然后在命令行中执行如下语句:

django-admin startproject mysite

其中 mysite 就是 Web 应用的名称。执行后会在你的 Script 目录下生成一个 mysite 目录,目录下就是一些项目文件。或者我们可以通过 cd 操作切换到其它目录开始项目。

创建成功后目录结构如下:

实际上我们现在已经写完了我们的第一个网站,我们可以进入项目的根目录:

cd mysite

然后运行服务端:

python manage.py runserver

执行该语句实际上就是运行了 manage.py 文件,控制台显示如下:

D:\CodeField\Python\Scripts\mysite>Python manage.py  runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
March 03, 2020 - 12:45:11
Django version 2.2.10, using settings 'mysite.settings'
\# 项目ip地址
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

我们可以看到项目运行在 127.0.0.1:8000 下,我们在浏览器输入该 ip 显示如下页面:

python django网页开发工具 python网站开发入门_django_02

到现在为止,我们不需要什么网络协议相关的知识就完成了环境的搭建和第一个项目的运行。但是在我们开始自己着手写一个网站之前,我们简单看一下一个网站是怎么运行的。

二、网络协议相关知识

在我们访问一个网站时,我们在浏览器输入网址(域名),然后通过域名系统(DNS)解析出 IP 地址,然后就开始了我们的网络请求。我们向服务器发出请求,也就是告诉服务器我们要找你拿东西。服务器接受了你的请求,然后经过一系列逻辑操作,将对应的:none;-webkit-font-smoothing:antialiased;box-sizing:border-box;margin:0px 0px 1.1em;outline:0px;">我们进入 mysite/mysite/urls.py 文件,代码如下:

from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

其实这个文件就是将 url 和函数建立关系,也就是路由系统。大家可以尝试在浏览器访问 localhost:8000/admin,这个也是 Django 本身预设的页面。

我们自己写一个路由关系:

from django.contrib import admin
from django.urls import path
\# 导入httpresponse
from django.shortcuts import HttpResponse

\#定义函数
def hello(request):
    return HttpResponse('hello world')

urlpatterns = [
    path('admin/', admin.site.urls),
    \# 将localhost:8000/hello 和函数hello建立联系
    path('hello/', hello),
]

我们定义了一个函数 hello,这个函数有个参数 request,request 中包含了我们的所有请求信息。现在我们暂时用不到,然后我们直接返回 HttpResponse ('hello world')。我们使用 HttpResponse 可以直接返回我们要在页面上显示的内容即可,除了文本,我们还可以显示 HTML 标签。

然后我们在 urlpatterns 中写 url 和函数的对应 path ('hello/', hello),第一个参数是 url 的名称,第二个参数为函数名称(不能加括号)。然后我们就可以访问这个页面了,在浏览器中输入 localhost:8000/hello,就可以显示 hello world 页面了。

在上面我们在浏览器中输入 IP,就是向服务器发送了一次请求,服务端通过 urls.py 中的路由关系,找到 hello 函数,在 hello 函数中执行一系列逻辑操作,然后通过 return 返回响应的数据。

三、完善项目目录

在上面的例子中,我们只是简单的返回一个字符页面,在我们实际生活中,页面要更加丰富。所以我们还需要 HTML 页面,另外还需要一些静态的资源。我们先把项目目录完善一下。

3.1 项目目录

最初始的项目只有 mysite 文件夹和 manage.py 文件,而实际上我们还需要一个 templates 文件夹存放一个 HTML 页面,另外我们还需要一个 static 文件夹存放静态文件(CSS、JS、图片、文件等)。完善后目录如下:

python django网页开发工具 python网站开发入门_html_03

然后我们将这两个目录在 setting 中配置一下。我们先配置 templates:

TEMPLATES = [
    {
        \# 修改该行
        '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',
            ],
        },
    },
]

我们找到 settings.py 中的 TEMPLATES 变量,修改成 'DIRS': [os.path.join (BASE_DIR, 'templates')]。然后我们再配置一下 static 文件夹,直接下 settings.py 下添加如下代码:

STATICFILES_DIRS = (
    \# 我们可以通过static访问静态文件
    os.path.join(BASE_DIR, 'static'),
)

另外我们注释一条语句:

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',
]

3.2 响应一个页面

在 MTV 模式中 templates 就是我们的模板层,也就是 MVC 中的视图层,我们在 templates 中放入 HTML 的页面模板,下面我们创建一个简单的 HTML 页面 hello.html,该页面中只有一张图片。

\<!DOCTYPE html\>
\<html lang="en"\>
\<head\>
    \<meta charset="UTF-8"\>
    \<title\>Title\</title\>
\</head\>
\<body\>
    \<img src="/static/1.jpg"\>
\</body\>
\</html\>

我们看到图片的路径是 /static/1.jpg,这里的 static 并不是目录 static,而是在 settings.py 中配置的 static。配置的时候可以目录和访问路径不同名。我们在 static 目录下放一张图片 1.jpg。

我们知道返回数据是在 urls.py 中实现的,我们进入该文件:

from django.contrib import admin
from django.urls import path
from django.shortcuts import render

def hello(request):
    \# 响应页面
    return render(request, 'hello.html')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/', hello),
]

这里我们使用 render 来响应页面,在调用 render 时,我们需要传入 request 和页面名称,因为我们上面配置了 templates 文件夹,所以直接写 hello.html 即可。然后我们就可以通过 localhost:8000/hello 访问 hello.html 页面了。

四、Django 知识补充

其实现在我们已经可以开发一个简单的网站了,但是我们还需要学习一点其它知识。

4.1 request 对象

在前面我们已经说过 request 是所以请求信息,但是一直没使用过。我们看一下 request 中有哪些信息。

1. 请求类型

request.method 中包含了请求类型的信息:

request.method

2. 请求参数

我们可以获取 GET 请求的请求参数:

request.GET.get('name')

其中 name 为参数名称。另外我们还可以获取 POST 请求的请求参数:

request.POST.get('name')

4.2 特殊标记

我们知道如何返回一个静态网页给用户,但是我们开发的是动态网站是需要根据用户操作实时修改数据的,这个时候就需要我们使用到特殊标记了。

我们编写一个 login.html 页面,在文件中添加一个特殊标记,如果登录失败显示失败,如果登录成功显示成功。

login.html

\<!DOCTYPE html\>
\<html lang="en"\>
\<head\>
    \<meta charset="UTF-8"\>
    \<title\>Title\</title\>
\</head\>
\<body\>
    \<form method="post"\>
        username: \<input type="text" name="username"/\>\<br/\>
        password: \<input type="text" name="password"/\>\<br/\>
        \<input type="submit"/\>
    \</form\>
            {{ login_status }}

\</body\>
\</html\>

其中 {{ name }} 格式的就为特殊标记。然后我们建立路由关系:

from django.contrib import admin
from django.urls import path
from django.shortcuts import HttpResponse, render, redirect

def login(request):
    if 'GET' == request.method:
        return render(request, 'login.html')
    else:
        name = request.POST.get('username')
        pwd = request.POST.get('password')
        if 'zack' == name and '123456' == pwd:
            return render(request, 'login.html', {'login\_status':'success'})
        else:
            return render(request, 'login.html', {'login\_status':'fail'})

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', login),
]

第一次请求为 GET,直接显示页面,然后我们用表单提交数据时请求方式为 POST,于是我们判断用户名密码,在显示页面的时候以字典形式传入参数。当用户名和密码输入正确时,会显示登录成功,当输入错误时会显示失败。

4.3 重定向

我们上面学习到的 render 的作用就是转发,有时候我们还需要使用到重定向。重定向的实现是通过 redirect 实现的。使用和转发类似:

return redirect('/login/')

使用重定向时,我们需要在路径前加 /

五、开发一个简单的网站

我们知道上面的知识后,就可以开始开发一个简单的网站了,页面上不会又太多讲究,主要是功能上的实现。下面就带大家实现一个自动生成词云的网站。

5.1 HTML 页面

一共有两个页面,一个用来输入生成词云的信息,一个用来显示词云,我们先看第一个。

\<!DOCTYPE html\>
\<html lang="en"\>
\<head\>
    \<meta charset="UTF-8"\>
    \<title\>Title\</title\>
\</head\>
\<body\>
    \<form method="POST" action="/wc/" enctype="multipart/form-data"\>
        \<input type="text" name="text"/\>
        \<input type="file" name="mask"\>
        \<input type="submit"/\>
    \</form\>
\</body\>
\</html\>

因为我们要上传图片文件,所以要设置 enctype="multipart/form-data"

然后是显示词云的页面:

\<!DOCTYPE html\>
\<html lang="en"\>
\<head\>
    \<meta charset="UTF-8"\>
    \<title\>Title\</title\>
\</head\>
\<body\>
    \<img src="{{ im\_url }}"\>
\</body\>
\</html\>

这里只有一个图片标签,资源路径为特殊标记。

5.2 建立路由关系

def wc(request):
    pass
def show(request):
    pass

urlpatterns = [
    path('admin/', admin.site.urls),
    \# 生成词云页面
    path('wc/', wc),
    \# 显示词云
    path('show/', show),
]

然后我们看看两个主要函数的函数体。

5.3 函数体

生成词云:

def wc(request):
    if request.method == 'GET':
        return render(request, 'WordCloud.html')
    else:
        \# 获取用户输入的文本,并使用jieba分词
        text = request.POST.get('text')
        word = jieba.lcut(text)
        text = " ".join(word)

        \# 上传文件
        mask_file = request.FILES.get('mask')
        file_path = os.path.join('static', 'masks', mask_file.name)
        f = open(file_path, 'wb')
        for chunk in mask_file.chunks():
            f.write(chunk)
        f.close()

        \# 读取图片成ndarray对象
        im = Image.open(file_path)
        mask = np.array(im)

        \# 生成词云
        wc_im = WordCloud(
            mask=mask
        )
        wc_im.generate(text)

        \# 保存词云
        file_path = os.path.join('static', 'save\_file', mask_file.name)
        wc_im.to_file(file_path)
        \# 重定向至显示页面
        return redirect('/show?file\_name=' + mask_file.name)

当然这里没用判断空字符串,也省略了许多功能。

显示词云:

def show(request):
    \# wc函数中我们使用get方式传入了词云的地址
    file_name = request.GET.get('file\_name')
    file_path = os.path.join('static', 'save\_file', file_name)
    return render(request, 'show.html', {'im\_url':'/'+file_path})

然后我们这个简单的网站就实现了。

六、在云服务器运行网站

为了方便,我选择了 Windows 版的服务器。在操作过程中只需要上面的步骤,搭建 Python 环境、安装 Django……

在我们搭建好环境后,也是以同样的方式完成操作。开始一个项目然后开始编写代码。上述在线演示如下:

生成词云