本文是在学习https://www.gitbook.com/book/djangogirlstaipei/django-girls-taipei-tutorial/details过程中整理,使用Python3.5,Django1.9.5,因软件版本问题,部分细节与教程中有差别。学习过程中不断遇到细节的问题需要解决,通过查看官方文档,google解决之,磕磕绊绊终于在Heroku部署完成了第一个Django project,学习过程也是点技能树的过程,没有其它方法,就是干。

一、Django的MTV架构处理request流程如下:


MTV

1、浏览器进行HTTP request;

2、Django根据URL configuration分配至对应的View;

3、View进行数据库的操作或其它运算,并传回HttpResponse内容;

4、浏览器根据HTTP response显示网页内容。


流程

二、创建项目mysite及名为trips的app

1、创建项目文件夹并cd到该文件夹:


创建文件夹

2、创建虚拟环境:


创建虚拟环境

3、切换至虚拟环境


切换虚拟环境


切换成功的状态

4、安装Django:如果使用python3,要用命令pip3


安装Django

5、创建Django project:


创建Django project

如果之前已经安装过Django,未在当前虚拟环境下安装,需要添加环境变量至PATH,否则报错:


命令未找到

需要将Django-admin所在目录添加到环境变量中:


设置环境变量并创建项目

添加环境变量至/.bash_profile后,只运行一次,下次再创建project需要使用source ~/.bash_profile 命令。

(path设置可参考:http://www.flakor.cn/2014-09-14-714.html)

下图为django-admin所在目录:


django-admin所在目录

6、查看manage.py帮助等:先cd到project目录再运行以下命令


查看help

如需查看manage.py中某个指令,可使用:


查看runserver的帮助

7、启动开发服务器–runserver:


启动runserver

在浏览器中输入网址:http://127.0.0.1:8000/,会看到项目已经在web server执行:


运行成功

8、用startapp命令建立名为trips的app:


建立app

9、将新建的app添加到setting.py,让Django知道管理哪些apps(app之间有先后顺序),

打开mysite/setting.py,找到INSTALLED_APPS,进行如下修改:


添加app

二、Views and URLconfs

1、Django Views:

       Django view是一个function,处理HttpRequest对象,并传回HttpResponse对象,Django接收到request后,将request中的内容封装产生HttpRequest对象,并将其当作参数传入对应的view function;将被传回的HttpResponse中包括HttpResponse.content、HttpResponse.status_code等。

2、创建一个名为hello_world的view:

在trips/views.py中输入以下代码:


输入代码

       以上代码做的事情是:从django.http模块中引用HttpResponse类,定义名为hello_world的view,当此view被调用时,返回包含字符串\”Hello World!\”的HttpResponse对象。

3、Django URL设置:

       Django需要知道URL与view的对应关系,例如有人浏览“http://127.0.0.1:8000/hello/”时,hello_world()这个function需要被执行,而这个对应关系就是URL conf(URL configuration)。

URL Conf:通常定义在urls.py;是一连串的规则(URL patterns);Django收到request时,会一一对比URL Conf中的规则,决定要执行哪个view function。

设置URL Conf:首先打开mysite/urls.py,先import刚写的view function,然后在urlpatterns中加入代码:url(r\’^hello/$\’, hello_world),如下图:


urls.py

       以上代码通过url() function 传入两个参数:regex和view,regex指定义的URL规则,regex用正则表达式(regular expression)来表示,r\’^hello/$\’表示的是hello/这种URL;view对应的是view function,此处指hello_world。

4、测试Hello World:

重新启动web server:


启动

在浏览器打开:http://127.0.0.1:8000/hello/:


Hello World!

三、Templates

1、添加HTML/CSS&动态内容:


trips/views.py

利用\”\”\” \”\”\”多行字符串来保持HTML代码的缩进,使用datetime模块的datetime.now()获取当前时间,再利用format字符串格式化来将当前时间带入到current_time,现在网页显示效果如下:


网页显示

此步骤是为了演示效果,实际使用时,通常把HTML/CSS代码独立出来,放在templates文件夹中,增加代码可读性以及方便调用。

2、创建templates文件夹:

首先在djangogirls/mysite下建立文件夹:


创建文件夹

其次需要修改mysite文件夹中setting.py的TEMPLATES设置,将\’DIRS\’的[]修改为:


修改DIRS

好让Django能够找到刚创建的templates文件夹:


修改后

然后在templates文件夹中创建hello_world.html,并将之前写在view function中的HTML代码复制到hello_world.html,现在mysite文件夹目录结构如下:


mysite目录结构

修改hello_world.html的代码:


hello_world.html

注意html代码中的{{current_time}},此处使用了Django Template语法。

最后,将view function hello_world修改如下:


view.py

view.py中使用的参数有:request–HttpRequest对象;template_name–要使用的template;dictionary–包含要新增至template的变量;render–生成HttpResponse对象。render用法:render(request, template_name, dictionary)。

此时重新加载http://127.0.0.1:8000/hello/,发现时间与系统时间不一致,google后得知需要修改setting.py中的TIME_ZONE为\’Asia/Shanghai\’:


TIME_ZONE

重新加载网页:


运行成功

四、Models

本章学习如何利用Django Model定义数据库的结构(schema),并通过Django命令创建数据库(Database)、数据表(Table)以及字段(Field)。使用Django Model操作数据库的好处之一是,转换数据库很方便。

1、设置数据库:

此处使用默认的SQLite,打开mysite/setting.py,DATABASES部分如图所示:


DATABASES

ENGINE表示要使用的数据库引擎,NAME指数据库名称。

2、Django Models:

打开trips/models.py,创建一个Post类并定义属性,Django会依据这个类创建数据表以及表中的字段:


创建Post类

Django默认为每个Model加上一个id字段,并将id设置为primary key(主键),简称pk,让每一份数据都有独一无二的ID。

Post中的Field属性含义如下表:


Field属性

3、同步数据库:

首先执行makemigrations命令:


makemigrations

这个命令会根据对Model的修改删除建立一个新的migration档案,让migrate命令执行时,可以依据此记录更新数据库。

然后用以下命令,让Django根据以上记录将model.py中的字段写入数据库:


migrate

结果应如图所示:


运行结果

migrate命令会根据INSTALLED_APPS的设置,按照app的顺序新建或更新数据表,将model.py中的更新与数据库同步。

五、Admin

本章学习如何设置Django Admin,并使用Django管理后台,完成Post的新增、修改及删除。

1、设置管理后台–将Django Admin加入INSTALLED APPS:

将Django Admin加入mysite/setting中的INSTALLED APPS,Django已经默认开启后台管理功能,如下图:


setting.py

2、设置管理后台–设置管理后台的URL:

为了可以从浏览器进入管理后台,需要设置对应的urls,此处将管理后台的网址设置为/admin/,确认mysite/urls.py的urlpatterns中包含下面的代码:


urlpatterns

3、设置管理后台–创建superuser:

使用createsuperuser命令来创建管理员帐号:


createsuperuser

注意:每个Django项目需要单独使用一个superuser帐号。

4、设置管理后台–注册Model class:

最后,要让Django知道,哪些Model需要管理后台,修改trip app里面的admin.py,并注册Post这个Model:


修改admin.py

5、使用管理后台–进入管理后台:

重新运行web server,进入http://127.0.0.1:8000/admin/并登录:


管理后台

AUTHENTICATION AND AUTHORIZATION区域可以管理使用者(User)和群组(Group);TRIPS区域中可以看到刚设置的Post Model,在这里可以执行Post的新增、修改、删除等功能。

可以试着新建一个Post:


add

需要填写的项目就是之前在model.py中创建的Post类中的属性。建立成功并保存后返回Post页面,会发现刚才创建的项目,显示为Post object:


Post object

Django通常以Post object来表示Post项目,项目多时不易辨认,可以通过def __str__修改Post的表示方式,修改trips/models.py:


def __str__

重新加载网页,发现Post显示方式变成了显示标题:


修改后

六、使用Django ORM操作数据库

上一章使用Django Admin对Post进行新增、修改及删除,但实际应用中,会使用Django提供的QuerySet API进行数据库操作(CRUD),CRUD指Creat(新增)、Read(读取)、Update(修改)、Delete(删除)等常见的数据库操作。

1、使用Django shell:

此处使用IPython,可以使用pip3来安装IPython(之前安装过,这次没有在虚拟环境中安装,会警告,入下图),使用shell命令进入Django shell:


启动shell

2、QuerySet API–Create:


Create

3、QuerySet API–Read:

可以使用all()查看所有Post:


all()

想查看部分数据时,可以使用get和filter:


get


filter

get返回符合条件的唯一数据,如果找不到符合条件的数据或多条数据符合条件,将返回exception;filter返回符合条件数据的列表,如果找不到符合条件的数据将返回空列表。

4、QuerySet API–Update:

可以使用update修改一条或多条数据,首先先筛选出想要修改的数据:


筛选id小于3的数据

将location修改为BeiJing:


update

5、QuerySet API–Delete:

可以使用delete将刚才修改的两条Post删除:


delete

可以看到,现在只剩下后面两条Post。另外,删除前面的Post后,后面Post的id没有变化,还是之前的id:


验证Post的id

注意:退出IPython重新进入后,想要操作数据库需要import要操作的Post,如重新进入IPython后未导入Post,会报错:NameError: name \’Post\’ is not defined,执行以下命令来导入:


import Post

七、Template tags

官方文档:https://docs.djangoproject.com/en/1.9/ref/templates/builtins/

为了生成完整网页,可能需要在template中执行一些Python代码,比如逻辑判断,for循环等。Django template tags可以使用在HTML文件中,类似Python语法,达到动态存取从view function传过来的变量,或是显示到浏览器之前进行一些简单的判断、转换、计算。

本章学习使用Django ORM进行数据库存取、取出全部posts传入template,并使用template tags与filters,生成网页。

1、创建首页–确认首页需求:

首页包括标题、照片、日期、正文。

2、创建首页–建立首页View:

首先建立一个view function–home():


home()

home()中impport了需要用到的Model Post;通过Post.objects.all()取得所有posts,并传入home.html这个template。

3、创建首页–设置首页URL:

修改url.py,将首页指向home()这个view function:


url.py

4、Template tags–创建首页的Template并显示post_list:

首先,在template文件夹中新建home.html:


home.html


访问网址

5、Template tags–显示Post中的数据:

观察网页,post_list是以list形式显示,为了显示每个post的数据,要使用for这个template tag:


for

现在修改home.html如下:


修改后

重新加载网页:


网页显示

6、Template tags–显示照片:

网页现在显示的是照片网址,修改template home.html,让网页显示照片:

把{{ post.photo }}修改成:


修改后

7、Template tags–处理没有照片的post:

这里用到 {% if %} 判断,将home.html修改如下:


if判断

以上代码判断如果post.photo有值就显示照片,否则就使用CSS class photo-default处理。

8、Template tags–Template filter:

Template filter可以在变量显示之前进行一系列操作,使用方法:


Template filter

:变量名称;:filter名称,如add、cut等;:要传入filter的参数。

使用方法举例–变更时间的显示方式:这里使用的是date,可以将datetime类型的对象,以指定的时间格式输出,此处将created_at时间显示为年/月/日:


date

9、完整的HTML和CSS:

最终版home.html如下:


home.html


home.html

访问网页http://127.0.0.1:8000/,效果如下:


网页

八、Dynamic URL

本章学习如何设置动态网址的URL conf,让每篇游记有单独的URL与页面。

1、建立单篇文章的View:

首先创建单篇文章所使用的view function,在trips/views.py中新增post_detail这个view:


post_detail

以浏览网址http://127.0.0.1:8000/post/5/为例,解释以上代码:

目前浏览文章的pk会传入view中,上面网址传入的pk为5(URL与pk的对应稍后设置,见本章第3节);当传入的pk=5,代表访客想浏览pk=5的那篇文章,利用ORM语法get,取得该片文章的Post对象:post = Post.objects.get(pk=pk),然后回传HttpResponse对象:将取得的post传入Template post.html,并呈现render后的结果。

2、设置对应的动态网址:

修改mysite/urls.py:


urls.py

以上代码的url部分使用regex(正则表达式)提取部分URL作为参数,分析如下:

(?P\\d+):\\d代表一个阿拉伯数字,+代表一个以上,所以\\d+就代表一个以上的阿拉伯数字,如0、99等;(?P)表示把这一串内容抓取出来,命名为pk,所以(?P\\d+)表示:抓取一个以上阿拉伯数字并将抓取的内容命名为pk。

3、创建单篇文章页面的Template:

在templates中创建post.html,代码如下:


post.html


post.html

这个template将post对象的属性(标题、正文等),利用{{ var }} 与template filter显示并格式化于HTML中,现在可以访问http://127.0.0.1:8000/post/5/查看网页效果(学习过程中,因数据库中数据有删除,pk从5开始,如果访问不存在的pk,会返回Post matching query does not exist.的报错)。

4、在home.py加入单篇文章的链接:

{% url %}:可以连接到特定view的template tag,语法是 {% url \'\’ %} ,根据在urls.py中的name值,找到对应的URL,也可以传入参数,如:


{% url %}

需要加入链接的地方有文章标题和Read More按钮,可以使用{% url %}来达成。

首先设置标题链接,打开home.html,找到:


修改前

将#修改为:


修改后

设置Read More链接,找到:


修改前

同上,将#修改为:


修改后

现在访问http://127.0.0.1:8000/,点击文章标题或Read More,可以访问文章详情页:


详情页

九、Deploy

本章学习如何将网站部署到服务器上,这里选择Heroku进行部署(Deploy)。

1、安装部署工具:


pip3安装库

2、部署准备:

为了让sever了解部署时所需要的安装环境,要做以下准备:

requirements.txt:在djangogirls目录下,用以下命令将虚拟环境中的Python依赖包名称提取到txt文件中:


pip3 freeze

因为Heroku使用PostgreSQL数据库,要手动在requirements.txt最后一行加上psycopg2==2.6.1,最终的requirements.txt如下(版本号可能不同):


requirements.txt

Procfile:创建一个Procfile文件并写入以下内容(没有任何扩展名):


Procfile

这行代码是告诉Heroku如何启动我们的应用,Gunicorn是一个用Python开发的WSGI工具,可用来启动Django网站,启动网站命令如下:


Gunicorn命令

runtime.txt:里面写入python-3.5.0,是为了让Heroku知道使用哪个版本的Python。

production_settings.py:前面章节通过修改settings.py来调整Django project的设置,但通常正式上线(production)的环境和开发/本机(development/local)环境有所不同,所以在mysite/mysite/下新建一个production_settings.py来存放部署时的设置:


production_settings.py

wsgi.py:WSGI是Python定义网页程序和服务器沟通的界面,为了让Heroku的服务能够通过这个界面与我们的网站沟通,修改mysite/mysite/wsgi.py如下:


wsgi.py

以上代码中,将dj_static导入,并在application上使用它,以协助我们部署static档案。

.gitignore:将不希望上传Git的文件名写入这个文件:


.gitignore

.gitignore是一个隐藏文件,可以使用以下代码进行显示及隐藏:


显示

将true换成false即可隐藏。

最后djangogirls文件夹的数据结构如下:


djangogirls

3、Deploy to Heroku:

在开始部署前,先到Heroku官网注册帐号,并安装Heroku工具箱。

Step 1:登录Heroku

输入以下命令,并输入注册的邮箱帐号及密码即可登录:


登录

Step 2:新增一个git repository

在djangogirls文件夹下新建一个git repository:


新增git repository

Step 3-1:新增Heroku app

现在要新增一个可以上传repository的地方:


新增heroku app

create后面不加名字将创建随机名称的Heroku app,Heroku app不可以重名。

Step 3-2:指定已经存在的app

如之前创建过Heroku app,可先查看app名称:


查看app

然后设定为想上传的app:


设定app

最后通过以下命令检查是否设置到正确的位置:


检查

Step 4:设置环境变量

利用heroku config:set命令设置环境变量,以确保未来Heroku执行任何命令时,都是使用部署专用的设置:


设置环境变量

Step 5:使用git push上传到Heroku

使用git push命令上传git repository后,会按照runtime.txt安装Python3.5.0,也通过pip安装requirements.txt中列出的库:


git push

报错 1:如遇到下面错误信息:


报错信息1

可通过下面的命令新增public key,然后重新git push:


解决办法

报错 2:在修改git repository中的文件后直接执行git push命令,可能会有如下报错(通过heroku logs命令查看):


报错信息2

这时需要重新添加git repository后再执行git push:


git add .

Step 6:启动web process

之前创建的Procfile文件告诉Heroku启动时要执行的命令,现在用以下命令启动web process,并指定只需要一个instance:


启动web process

Step 7:Django project初始化

Django现在已经成功启动,但还需要进行数据库初始化,利用heroku run可以执行命令:


heroku run

并为新数据库创建一个superuser:


createsuperuser

Step 8:在浏览器查看网站

可以通过heroku open命令查看部署到Heroku的网站。因为数据库和本地不同,之前的文章需要重新输入。

如果对网站进行了修改并想更新到Heroku,要先进行git commit再push到Heroku即可。