15158846557 在线咨询 在线咨询
15158846557 在线咨询
所在位置: 首页 > 营销资讯 > 网站运营 > 如何用Python Django创建网站?系列文章04(持续更新)

如何用Python Django创建网站?系列文章04(持续更新)

时间:2023-07-24 03:09:01 | 来源:网站运营

时间:2023-07-24 03:09:01 来源:网站运营

如何用Python Django创建网站?系列文章04(持续更新):这个帖子会在之前积累的Ubuntu+Python+Django教程基础上搭建 投票/问卷调查 网站。

一、前期的准备工作

  1. 需要准备一台PC或者笔记本,安装上Ubuntu16.04版本,参考下面这个教程:



2. 需要租一台阿里云服务器,选择安装Ubuntu16.04版本,参考第二个教程开始部分:

注意⚠️ :经常有同学一开始会问说,能不能用windows系统或者macOS系统来对接阿里云的Ubuntu系统?

答案肯定是可以的,只是这个过程会遇到一些系统级别的bug。比如,为了把本地的django项目迁移部署到服务器,你需要在macOS系统生成django项目所需要的安装包列表,其数量可能会远远多于你实际需要安装的软件包。所以,我们还是比较推荐用纯命令窗口的 本地Ubuntu -- 阿里云Ubuntu 的远程连接模式。







二、搭建开发环境

1. 需要学习Python编程语言,选择安装PyCharm,参考系列文章01教程(在30行)如下:

Ubuntu16.04版本自带Python2和Python3,而且我们已经验证过了Python3.5是能够满足创建django网站项目需求的,所以,我们直接用系统自带的Python3.5就可以了。




2. 需要学习Linux系统的架构和常用命令,参考系列文章01教程(在50行)。

一开始学习一门新的语言会觉得内容太多无从下手,怎么办?初学者可以从最高频的语句或者命令入手(限定知识的范围来降低学习难度),配合上操作(编程是一种技能),逐渐扩展到细分领域,效果就会很好。学习本质上是一个逐渐建构的过程




3. 安装MySQL数据库,参考以下教程的第三点:

如果安装过程跳出下面这个界面,提醒你设置数据库密码,说明你走在了正确的道路上:




4. 安装python3-pip

·先更新,

apt-get update

·再安装

apt-get install python3-pip

这里有可能出现权限问题,在命令行前面加上sudo,以管理员权限来运行更新和安装,需要输入一次系统密码。从安装python3-pip开始,之后的所有的软件安装,都是基于pip3来完成的。




5. 利用python3-pip来安装虚拟环境virtualenv,具体参考的教程如下:

安装虚拟环境的命令并不复杂:

sudo pip3 install virtualenv sudo pip3 install virtualenvwrapper然而,启动虚拟环境却让人有点纠结,存在两种开启模式:一种是简便模式,也就是上面这个教程所采取的方法,这种方法的好处是创建虚拟环境的时候,文件夹里边比较干净没有杂七杂八的内容,进入虚拟环境的状态命令也比较简单,用workon XXX就可以启动虚拟环境。

另外一种是原始模式,好处是不需要事先做涉及.bashrc文件的操作,缺点是文件夹里边会有各种杂乱的内容,启动虚拟环境的命令也会稍微有点麻烦,比如,source XXX/bin/activate。我自己在本地Ubuntu系统上workon成功了,但是,在阿里云服务器Ubuntu系统上没有成功。所以,我现在比较推荐的方法是原始模式,这也比较符合我一直以来的“怂”的特点,一旦有风险就选择避开。

推荐创建和启动虚拟环境的命令如下:

·创建虚拟环境的语句:

virtualenv GP2

·激活虚拟环境的代码:

source GP2/bin/activate

·退出的命令是:

deactivate




6. 指定版本安装django

pip3 install django==1.11.7




7. 为了配合django项目的具体需求,我们还需要额外安装一些软件包,比如:

pip3 install PyMySQL
pip3 install pytz

·前者PyMySQL是一个数据库驱动模块,要想将django与mysql数据库连接,需要在django项目的初始化__init__.py文件中添加专门的语句:

import pymysqlpymysql.installasMySQLdb()


·后者pytz是专门为数据库的表格添加时间信息有关的字段服务的。

Django开发者并没有一开始就深思熟虑地考虑时区问题,这个部分是在美国本土之外的开发者,也就是我们东方人,形成的全球化视角的优势之一?







三、开发民意调查/投票网站

这个教程所演示的投票网站主要是想实现以下两个目标:

第一,后台的网站管理功能部分,管理员可以添加、修改、和删除调查问卷。

第二,公开的网站投票网页部分,实现的是用户网上投票和浏览结果的功能。




1. 启动一个已经创建好的虚拟环境GP2

打开已经安装了Ubuntu系统的笔记本电脑,点击Terminal客户端,按照常规的操作进入到已经创建好的GP2文件夹。

linux系统的常用命令有两个:ls相当于眼睛 ,cd相当于进入

激活虚拟环境的命令,之前我们说过,我们选择了保守模式

source GP2/bin/activate




2. 创建一个名叫myPolls的Django项目

进入到GP2文件夹中之后,我们要创建一个叫做myPolls的Django项目:

> django-admin startproject myPolls这里的myPolls代表的是民min意yi调查问卷polls的意思,my又有“我的”含义,一语双关。




3. 在项目文件夹中创建一个app01_myPolls应用

进入到myPolls文件夹,利用下面的命令创建一个名叫app01_myPolls的应用:

python3 manage.py startapp app01_myPolls 利用tree命令可以查看整个文件夹的结构:

文件夹有两个,一个是项目同名的文件夹myPolls,里边有(1)项目的启动文件__init__.py(之前说的数据库连接语句pymysql就是存放在这个位置);(2)项目配置文件settings.py,所有有关项目设置的参数都在这个文件里边;(3)项目的路由urls.py文件是整个项目的入口,用户通过url访问服务器,最先对接django项目的就是该文件;(4)最后一个是wsgi.py 文件,它是一个WSGI兼容的Web服务器的入口,用来运行当前的Django项目。

另外一个是app01_myPolls文件夹,里边有(1)应用后台管理文件admin.py,(2)应用配置文件apps.py,(3)应用初始化文件__init__.py,(4)模型文件models.py和(5)视图文件views.py等。

为了更好地理解Django项目MTV架构,我们来看一张图:

用户先是通过浏览器上的网址url进入到Django项目中,最先对接的就是项目文件夹中的urls.py文件,然后进入到应用app01_myPolls的views.py文件,在这个文件中会经历两重操作,一个是通过models来获取数据库中的数据,另外一个是以templates来获取网页的模版,最后将两者渲染render之后返回给用户浏览。

从这个角度来看,MTV在整个Django项目中,M(models.py)有了,V(views.py)也有了,唯独没有T(templates)。这个模版部分的文件夹templates和其中的.html文件,都是需要我们在PyCharm中手动添加和创建的。




4. 添加templates文件夹并修改与其对应的setting.py中的内容

打开PyCharm开发者工具:

点击打开myPolls项目文件夹,如下图所示:

一开始项目进来,因为最先运行的是myPolls项目文件夹中的urls.py文件,所以我故意双击点开这个文件,让大家看到里边的内容。实际上,一开始打开项目文件夹时,右侧是空的,没有显示任何一个具体文件的内容。




打开PyCharm开发者工具,最先要做的事情是添加templates模版文件夹。这一步具体实现的方法是,在左边上面的myPolls项目根目录文件夹的位置右键点击,选择新建文件夹Directory,这样才能保证这个文件夹创建的位置与应用app01_myPolls文件夹在同一级目录中。同时,特别需要强调的是,这个添加的过程,还要伴随2个操作:

第一个操作是,在添加了文件夹之后,在PyCharm中要右键点击文件夹templates,如下图所示:

Mark Directory as --> Template Folder,

这个把templates文件夹标记为模版文件夹“Template Folder”的过程,不会改变项目的任何代码,但是,标记了Template Folder会影响之后PyCharm的代码提示功能。




第二个操作是,修改settings.py文件中55行左右的位置,在TEMPLATES中,找到 'DIRS': [],在这个中括号中添加一段代码:

os.path.join(BASE_DIR,'templates'),

如下图所示:




有了模版文件夹templates之后,我们就可以往里边添加.html文件了(这里只是提一下,并没有实际操作,后面会有具体的创建.html的操作)。

.html是什么?

html是超文本文件,文件里边包含一些标签和数据,代表着“网页”的结构和内容。所谓的超文本,就是在文本的基础上,还包含有声音,图片和视频等多媒体文件。那么这些多媒体文件放在哪里呢?

答案是static。

实际上,我们看到的“网页”一般都是由三个部分构成:html5 + css3 + javascript,css决定了“网页”的样式风格,js决定的是具体的动作。我们把.html放在templates文件夹里边,那么css文件和js文件放哪里呢?

答案仍然是static。




5. 添加static文件夹并修改与其对应的setting.py中的内容

在PyCharm开发者工具左边上面的myPolls项目根目录文件夹的位置鼠标右键点击,选择新建文件夹Directory,将其命名成static。

然后,在settings.py文件最后一行的后面添加代码:

STATIC_URL = '/static/' #最后一行

STATICFILES_DIRS = [

os.path.join(BASE_DIR, 'static'),

]

简单总结第4和第5步,"添加templates和static文件夹,并在配置文件中添加它们的路径"。




6. 设置项目的解释器

在第1步,我们启动一个虚拟环境GP2,采用的是Python3.6版本。但是,这些在命令窗口Terminal中完成的操作,PyCharm是不能自动识别的。因此, 当我们进入到PyCharm环境中时,切记要在File菜单的Settings选项里设定整个项目的解释器,指向哪个虚拟环境,用哪个Python版本。

在Settings里边有两个选项,Project Structure 和 Python Interpreter,我们选择Python Interpreter,然后在下拉菜单中选择带有Show All选项,如下图所示:

点击之后,选择其中的Python 3.6(GP2)选项,见下图:

然后我们会看到:

点击Apply按钮,再点击OK,项目解释器设置完毕。




7. 注册应用app01_myPolls

我们在创建myPolls项目之后,紧跟着创建了一个app01_myPolls应用,这个应用myPolls项目是不认的。为什么不认?因为这个应用并没有注册!

之所以没有注册,是因为应用本身是独立于项目存在的,这个可能是Django开发者一开始就设定好的,这样做的好处是方便把某个应用从一个项目迁移到另外一个项目。考虑到高内聚,低耦合,可扩展,和可维护是一个优秀程序员的金标准。应用和项目解耦合的结果是,在用命令创建应用app时,它是独立进行的,不会自动地在项目中注册。如果你要把创建的应用纳入到项目中,就需要手动注册一下。怎么才能手动注册呢?

我们要打开myPolls项目的同名文件夹myPolls下的settings.py文件,把app01_myPolls应用写入到INSTALLED_APPS里边:




8. 修改配置setting.py文件中的一些项目(host, code, & timezone)

除了添加了templates和static路径信息,注册了应用之外,还剩下一些配置参数需要修改:

(1)ALLOWED_HOSTS = [],修改成ALLOWED_HOSTS = [“*”]。

(2)LANGUAGE_CODE = 'en-us',修改成LANGUAGE_CODE = 'zh-hans'。

(3)TIME_ZONE = 'UTC',修改成TIME_ZONE = 'Asia/Shanghai'。

(4)USE_TZ = True,修改成USE_TZ = False。

配置文件中的这些项目修改好之后,就剩下最后一个信息,数据库配置信息。




9. 配置数据库db_myPolls

注意MTV那张流程图中,最底层是数据库Database。要把PyCharm和MySQL数据库连接起来,这就需要配置两个地方:一个是初始化的时候,需要载入pymysql驱动;另外一个是在配置文件settings.py中的80+行,需要修改数据库相关的信息。

A. 修改项目初始化文件

点击myPolls项目文件夹中的__init__.py文件,输入下面这段代码:

import pymysqlpymysql.install_as_MySQLdb()


B. 修改配置文件中的数据库相关信息

点击myPolls项目文件夹中的settings.py文件,将下面这段代码:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }}替换成:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'db_myPolls', 'USER': 'root', 'PASSWORD': 'Psycho0810', 'HOST':'localhost', 'PORT':'3306', }}按照习惯,我会把数据库的名字命名成db_项目名称,也就是这里的db_myPolls。我们要在mysql中把这个叫做db_myPolls的数据库创建出来。按理说,这个操作是要从PyCharm开发者工具切换到Terminal终端命令行窗口来完成。PyCharm已经集成了命令窗口,所以这个时候,只需要点击整个PyCharm界面的左下角位置三个选项:“TODO”,“Python Console”,和“Terminal”,其中的Terminal选项,就可以打开终端。




C. 如何在mysql中创建db_myPolls?

在命令行中输入

mysql -uroot -p

它会要求输入密码,把之前设定好的密码输入敲回车,就可以进入到mysql环境中。




在mysql环境下建立一个新的数据库db_myPolls的代码如下:

mysql> create database db_myPolls charset=utf8;

这里要注意别忘记写charset=utf8这句话,因为,如果没有这句话,你没有办法导入中文。




这个时候可以调用下面这句命令看看mysql里边都有哪些数据库:

mysql> show databases;




+--------------------+

| Database |

+--------------------+

| information_schema |

| db_mBlog |

| db_psyBlog |

| db_myPolls |

| mysql |

| performance_schema |

| sys |

+--------------------+

7 rows in set (0.01 sec)




D. 手动连接myPolls项目与db_myPolls数据库

点击右侧竖着的那两个选项中的"Database",然后点击“+”号-->选择Data Sources这个选项中的MySQL,如下图所示:

这个时候会弹出一个界面:

小心!!这是个坑,因为一般人进入这个界面,想当然地会认为是从第一个编辑框Name开始填写,错了!!!你只需要填写User + Password + Database就可以,它会自动把信息合并了显示在Name对着的编辑框中,如下图所示:

这时候你点击一下“Test Connection”按钮,它如果显示打勾,说明连接数据库通过了测试。点击Apply应用当前设置,再点击OK,PyCharm与MySQL数据库的连接就建立成功了。




小结:在虚拟环境中,创建Django项目和应用之后,通过添加文件夹,修改配置文件,设定解释器,和连接数据库等一系列前期的操作,我们的PyCharm进入到了整装待发的状态。

10. 小试牛刀:制作一个Hello World

一般整个项目的框架搭建完后,都是会拿一个最简单的“Hello, World!”试着运行一次,向互联网世界宣告“我来啦!”,以及测试一下Django环境是不是搭建好了。

用户通过在浏览器中输入网址url访问服务器应用,这个url请求在Django项目中是发给了项目文件夹myPolls中的urls.py来处理的,我们来截个图:

这个urls.py是在整个项目下的,为了方便管理urls,Django发展出一套方法,可以在项目下的urls.py中设置include,将项目下的urls.py引导到应用下的urls.py。可是,应用下没有urls.py啊?我们手动建一个。在应用文件夹app01_myPolls中新建一个urls.py文件,输入:

urlpatterns = [

url(r'^hello', views.hello, name='hello'),

]

这句话的意思是,如果你在应用网址后添加hello,它就会触发视图views.py文件中的hello回调函数。

重新切回到项目下的urls.py文件,输入:

urlpatterns = [

url('admin/', admin.site.urls),

url(r'^app01_myPolls/', include('app01_myPolls.urls', namespace='app01_myPolls')),

]

这句话的意思是,如果你在网站的ip地址或者域名后面添加应用app01_myPolls,它会自动导向应用app01_myPolls文件夹中的urls.py文件。

注意⚠️:这个时候的include下面有红色波浪线,说明include这个方法所在的模块还没有导入进来。这个时候就要进行一次操作 "alt + enter",它会自动提示你是不是要从django.conf.urls中载入include方法,用鼠标点击或者敲回车即可完成操作。这个地方专门截个图,感受一下PyCharm作为Python+Django编程神器的威力:

神操作(alt + enter)完成之后,原来上面那句话就会在url后面增加include:

from django.conf.urls import url, include

原来include下面的红色波浪线提示就没了。

这个神操作也可以运用到应用app01_myPolls下的urls.py,url,views下面都有红色波浪线提示,操作过载入相应的模块之后,红色波浪线就消失了。再截图一起感受一下:

注意文件上方的两行代码,它们是后来新添加的:

from django.conf.urls import urlfrom app01_myPolls import views


最后还剩下hello这个函数,这个函数是指向views.py文件的,但是在views.py文件中这个函数是不存在的。同样把鼠标放在这个单词上,同时按下"alt + enter"就可以看到:

敲回车,就会瞬间切到views.py文件中,

这个函数的代码是自动添加上去的,

def hello(request): return none这个函数中,回调函数返回值是none,需要修改成

HttpResponse("Hello World!")

这个HttpResponse下面也是有红色波浪线的,需要神操作载入相应的模块。




自此,第一个hello world网页就做好了。我们可以在PyCharm下面的命令窗口中输入

python3 manage.py runserver在谷歌浏览器的网址输入栏中敲入:

127.0.0.1:8000/app01_myPolls/hello

敲回车,就会看到下面这个画面:

说明之前所有的操作都是有价值的。我们可以基于现在这个Django框架,建构出我们想要的问卷调查网站。










11. 第一个目标:实现对后台网站的管理功能

后台网站管理分为两个部分,第一是问卷的数据,包括题目Question和选项Choice;第二是网站的用户,分为普通用户和超级管理员。

我们先来实现Question和Choice两个模型的设计和构建:

数据库db_myPolls包含问题Questions和选项Choices两张表格,其中问题表格是主表,选项表格是子表。以主表Questions的question_id字段作为外键关联一张子表Choices。

外键(Foreign Key)是数据库的一个很重要的概念。当两张表存在关联字段的时候,利用外键可以保证主表和从表的一致性和完整性。

定义Questions和Choices两个模型的代码如下图所示:

在线问卷调查系统包括两个模型/表格:问题(Questions)和选项(Choices)。问题Questions模型包含两个字段,分别是问卷内容(question_text)和提交时间(pub_date),同时问题(Questions)模型包含一个叫做was_published_recently()的方法,用于判断问卷是不是最近(一天内)发布的;Choice同样包含两个字段选项内容(choice_text)和选项得分(votes)。这里要注意的是,一旦对表格中的字段进行了关联外键的操作,也就意味着每一个选项都必然属于一个问卷,即构成了所谓的多对一的关系。

文件app01_myPolls/models.py中的代码分享一下:

#!/usr/bin/python# -*- coding: UTF-8 -*-from django.db import modelsfrom django.utils import timezoneimport datetimeclass Questions(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') def was_published_recently(self): return self.pub_date >= timezone.now() - datetime.timedelta(days=1) def __str__(self): return self.question_textclass Choices(models.Model): question = models.ForeignKey(Questions, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) def __str__(self): return self.choice_text上面代码中每一个类就是一个Django模型,它们都继承自ddjango.db.models.Model类,而模型的每一个属性都是Field类的实例。模型对应数据库表格,每个模型的属性变量对应一个数据库表格的字段。

为了让模型文件models.py中的代码生效,我们需要进行两步十分关键的操作,一步是生成迁移文件makemigrations,另外一步是迁移migrate。切换到命令窗口,输入两次命令并运行:

python3 manage.py makemigrations


python3 manage.py migrate


先对整个PyCharm窗口进行截图,方便大家对迁移命令的运行有一个直观的印象:

再分享命令窗口的信息:

(GP2) psyjt@psyjt-ThinkPad-X1-Carbon-2nd:~/Projects/Project_Django/GP2/myPolls$ python3 manage.py makemigrationsMigrations for 'app01_myPolls': app01_myPolls/migrations/0001_initial.py - Create model Choices - Create model Questions - Add field question to choices(GP2) psyjt@psyjt-ThinkPad-X1-Carbon-2nd:~/Projects/Project_Django/GP2/myPolls$ python3 manage.py migrateOperations to perform: Apply all migrations: admin, app01_myPolls, auth, contenttypes, sessionsRunning 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 app01_myPolls.0001_initial... 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 sessions.0001_initial... OK(GP2) psyjt@psyjt-ThinkPad-X1-Carbon-2nd:~/Projects/Project_Django/GP2/myPolls$ 所有这些操作,都会作用在数据库上。我们可以通过打开PyCharm右侧的Database,看看是不是除了Django自带的一系列数据库表格,还有我们新创建的Questions和Choices表格?

问题和选项表格都在里边,创建成功!欧耶!!

出于好奇心,我们把问题Questions和选项Choices两个表格打开看下。

·先看问题表格:

问题Questions表格有三个字段,除了定义好的question_text和pub_date以外,还有一个自动添加的id字段,而且很明显它是主键primary key(简称pk)。由此我们可以看出,模型定义的时候,它会自动添加id主键。

·再看选项表格:

选项Choices表格有四个字段,除了事先定义的choice_text,votes和关联的外键question_id以外,同样会有一个自动添加的id主键。

看到这里,大家已经想到了,定义模型只是相当于给整个Django项目的底层数据库以表格的形式搭建了一个框架,但是,表格里边是空的,没有内容,需要某个角色通过某种方式把内容添加进去。

我是超级管理员
什么角色?

当然是我们整个网站的超级管理员同志。

超级管理员说:“我是谁?”,“我从哪里来?”,“我能为这个项目做什么?”

·我是谁?

超级管理员是整个网站后台管理权限最高的用户,我们会给它一个酷炫的名字,叫做SuperUser。

·我从哪里来?

超级管理员是通过Python3+Django项目根目录中的manage.py文件中自带的命令createsuperuser来创建的。

python3 manage.py createsuperuser·我能为这个项目做什么?

超级管理员可以实现对用户的管理,而且它还能添加、修改和删除数据库各个表格中的内容。具体的实现,需要用到admin.site.register命令,打开app01_myPolls文件夹中的admin.py文件,通过输入最后一行内容配合上神操作(alt + enter)添加代码如下:

from django.contrib import adminfrom .models import Questions, Choicesadmin.site.register(Questions)admin.site.register(Choices)有了这两句,超级管理员登录之后,不仅可以管理用户,也可以管理问题Questions和选项Choices表格中的数据内容。我们来看看登录界面:

还有登录进去之后的管理界面:

这个界面就允许超级管理员手动添加问题和选项表格中的具体内容。我们先来添加3个问题,然后再给这三个问题添加选项。添加问题的界面截图如下:

添加选项的界面如下图所示:

省略中间手动操作的过程,等以后我们变厉害了,这个手动的过程是可以用run代码来实现(这个挑战性的任务,已经由我们实验室一位叫做ZYX的大佬搞定了,用了数据库SQL语言;而且我们在网上也找到了更简便的方法,不需要调用SQL,只需要Python语言也能够搞定)。我们在考虑用户将题库制作成excel表格,网站只需要提供一个接口,用户点击按钮上传本地excel文件,就可以自动化导入到数据库中的方法。

手动添加数据成功之后,我们通过PyCharm中数据库可视化工具来查看添加之后两个表格中的内容,先看问题Questions表格中新添加的内容:

再来看选项Choices表格里边的数据:




到目前为止,我们的投票/民意调查问卷系统已经有了管理员账号,有了网站后台的管理系统(Django自带的),并且我们还运行了网站后台,用超级管理员登录并在表格中添加了数据内容。但是,整个网站还缺少公开的网站首页,投票网页和投票结果展示网页。







12. 第二个目标:实现用户网上投票和浏览结果的功能

在Django项目中,每一个网页或者其他内容都是通过视图呈现出来的,每一个视图就是一个Python函数或者方法(根据需要有时需要额外增加一个Python函数或者方法,并通过重定向指向另外一个视图函数)。总体上来说,Django是通过url确定调用哪个视图函数,而它们又都取决于一个整体的网站设计构想,如下图所示:

我们要实现的前端网页的构想,主页index、投票details和结果results三个视图,以及处理投票的vote函数,都是围绕整个投票/民意调查系统的设计框架展开的。

整个问卷系统的入口是项目myPolls文件夹下的urls.py文件,

进而借出include方法触发应用app01_myPolls文件夹下的urls.py。在该应用路由文件中,针对3个视图,包括index,details,和results,还有一个vote处理函数,我们要在应用路由urls.py文件中添加四个url映射,如下图所示:




小贴士:为超链接添加命名空间

这里专门在urls中植入了 命名空间,

namespace='app01_myPolls'

和类似这样的,

name='index'

命名空间第一是可以有效地对变量进行隔离,防止名称相同的变量之间调用混乱的问题;第二是可以配合反向解析reverse,在重定向的时候,有时候用reverse比较便利;第三是在模板中采用命名空间的形式来确定超链接,是Django项目比较常规的操作。




这里再需要补充一个url路由知识,就是,如果需要从url中获取一个值,需要对正则表达添加小括号。而且,一旦在url正则匹配中添加了小括号()来获取参数,在请求调用的函数中必须有接收的形参。以投票网页details为例子,url是这么写的:

url(r'^details/(/d+)$', views.details, name='details'),那么,视图views.py文件中的details函数就需要有专门的形参来获取传入的参数。

def details(request, question_id): return None在视图views.py文件中代码,截图如下:

小括号中的(/d+)代表的数字就传给了question_id这个参数。完整版本的views.py文件中的代码分享如下:

from django.http import HttpResponse, Http404, HttpResponseRedirectfrom django.shortcuts import render, get_object_or_404from django.urls import reversefrom app01_myPolls.models import Questions, Choices# Create your views here.def hello(request): return HttpResponse("Hello World!")def index(request): all_questionslist = Questions.objects.all() context = {'all_questionslist': all_questionslist} return render(request, "index.html", context)def details(request, question_id): try: question = Questions.objects.get(pk=question_id) context = {'question': question} except Questions.DoesNotExist: raise Http404("问卷不存在") # return redirect(reverse("appPolls:index")) return render(request, "details.html", context)def results(request, question_id): question = get_object_or_404(Questions, pk=question_id) context = {'question': question} return render(request, 'results.html', context)def vote(request, question_id): question = get_object_or_404(Questions, pk=question_id) try: selected_choice = question.choices_set.get(pk=request.POST['choice']) selected_choice.votes = selected_choice.votes + 1 selected_choice.save() except(KeyError, Choices.DoesNotExist): return render(request, "details.html", {'question': question, 'error_message': "还没有选择任何项目"}) return HttpResponseRedirect(reverse('app01_myPolls:results', args=(question.id,)))每一个视图函数都负责一个具体的业务逻辑,视图执行结束之后会返回一个包含页面内容的HttpResponse对象或者异常信息。

什么是异常信息?

我们有时候访问网页失败,会跳出一个404错误,就是典型的出现异常情况后浏览器呈现给用户的反馈信息。404错误是一个比较常见的网页访问的错误,当被访问的url资源不存在的时候,浏览器就会抛出这类错误。例如,上面的details视图函数,

try: question = Questions.objects.get(pk=question_id) context = {'question': question} except Questions.DoesNotExist: raise Http404("问卷不存在") # return redirect(reverse("appPolls:index")) return render(request, "details.html", context)如果这个时候,我们故意在浏览器中输入

http://127.0.0.1:8000/app01_myPolls/1000程序就会抛出异常,如下图所示:

这当然是我故意把url修改了导致的,一般情况下是不会出现这种情况的。由于404错误是一个非常常见的网页异常,所以Django也提供了一个简写方法:get_object_or_404。所以在details视图函数中我们使用了get_object_or_404()。




解释完异常情况处理之后,我们先来看index视图函数的功能是返回所有Questions表格中能够查找到的调查问卷。代码中的render就是渲染函数,它有三个参数,第一个request是请求变量,第二个是模板.html文件名,第三个是传入参数上下文变量context,一个类字典变量。当引用render函数之后,代码中就不需要httpResponse函数了,可以理解为render是HttpResponse的一种更为简洁的更高级的版本,它会先载入模板,然后基于传入的参数context中的key-value对应关系,将事先埋藏在模板中的块和变量替换为具体的值(渲染应该是这样一个替换过程的统称),最终返回给用户(的浏览器)。




第一个视图函数是index,可是它的模板文件“index.html“还没有创建,需要在templates文件夹中创建。该文件里的h5的代码分享如下:

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>问卷调查网站首页</title> {% load static %} <link rel="stylesheet" type='text/css' href="{% static 'style.css' %}" /></head><body><div id="container"> <br><h2> 感谢您参与我们的问卷调查:</h2>{% if all_questionslist %}<ul> {% for question in all_questionslist %} <li> <a href="{% url 'app01_myPolls:details' question.id %}">{{ question.question_text }}</a> </li> {% endfor %}</ul>{% else %}<p>还没有调查问卷!</p>{% endif %}</div></body></html>这个H5文件在头文件head位置引入了css文件,这个我们之后会介绍它具体是怎么实现的,暂时按下不表。我们按照自上而下的顺序,介绍整个H5文件中代码的含义:

A,我们在主体body位置增加了一个id标记为"container"的div盒子,目的是希望实现网页内容的居中样式效果。

B,{% if all_questionslist %} + {% else %} + {% endif %} 就是典型的Django模版的格式,Django项目会自动将代码解读为一个 if + else + end的组合。这句话的意思是说,如果我们传入的变量 all_questionslist 存在的话,就执行 for循环;如果不存在,就返回“还没有调查问卷!”

C,{% for question in all_questionslist %} + {% endfor %} 是for循环,其中的代码是罗列出所有的问卷题目,并且设定它们点击之后的网址url是指向特定问卷的具体投票网页的。

D,上面代码中的双大括号形式 {{ question.question_text }} 是Django模版语言中的属性访问语法,采用英文句点的形式访问变量的属性,其中question是视图通过字典形式传递给模版的变量,通过句点“.”访问question的属性question_text。







我们看下问卷调查网站首页的样子:

因为css文件还没有设置,所以网页展示的样式还比较原始。我们后面会通过css文件的配置来优化网页的样式,让它显得更美观一些。

我们有3个视图函数,自然需要三个.html网页模板。index视图对应的index.html模板文件已经分享过了,还需要分享details.html文件的代码:

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>投票页面</title> {% load static %} <link rel="stylesheet" type='text/css' href="{% static 'style.css' %}" /></head><body><div id="container"> <br><h2>{{ question.question_text }}</h2><form action="{% url 'app01_myPolls:vote' question.id %}" method="post"> {% csrf_token %} {% for choice in question.choices_set.all %} <input type="radio" name="choice" id="choices{{ forloop.counter }}" value="{{ choice.id }}" > <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label> <br> {% endfor %}<br><br> <input type="submit" value="提交" /></form><br></div></body></html>以及results.html文件中的代码:

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>投票结果页面</title> {% load static %} <link rel="stylesheet" type='text/css' href="{% static 'style.css' %}" /></head><body><br><div id="container"><h1>{{ question.question_text }}</h1><ul> {% for choice in question.choices_set.all %} <li>{{ choice.choice_text }} -- 记票{{ choice.votes }}次</li> <br> {% endfor %}</ul><br><a href="{% url 'app01_myPolls:index' %}">返回首页继续投票</a></div></body></html>














所有三个.html文件都内置了.css,

{% load static %} <link rel="stylesheet" type='text/css' href="{% static 'style.css' %}" />我们要在static文件夹中新建.css文件,输入下面这段代码:

li { color: green; text-decoration:none; list-style-type:decimal;}html { height:100%;}body { background-color: rgb(255,255,255); height:100%;}#container { background-color: rgb(245,245,250); width:600px; height:100%; margin: 0 auto;}h2 { text-align: center;}span { margin-left: 230px;}我们一起感受一下增加了样式的网站首页的呈现效果:

投票网页的效果如下:

结果网页的效果:

经过两轮投票,针对第一个问题“你喜欢心理学吗?”我都点了喜欢。我们来看看数据库里边的记录情况:




如果想把当前Django项目部署到阿里云服务器,可以参考我之前写的一个教程:




写到这里,这个硬核教程就写完了,希望这个教程能够开启您的互联网梦想♥️

有问题可以加QQ或微信一起探讨:10045198



























关键词:文章,系列,持续,更新,创建

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭