本文是在学习https://www.gitbook.com/book/djangogirlstaipei/django-girls-taipei-tutorial/details过程中整理,使用Python3.5,Django1.9.5,因软件版本问题,部分细节与教程中有差别。学习过程中不断遇到细节的问题需要解决,通过查看官方文档,google解决之,磕磕绊绊终于在Heroku部署完成了第一个Django project,学习过程也是点技能树的过程,没有其它方法,就是干。
一、Django的MTV架构处理request流程如下:
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
5、创建Django project:
如果之前已经安装过Django,未在当前虚拟环境下安装,需要添加环境变量至PATH,否则报错:
需要将Django-admin所在目录添加到环境变量中:
添加环境变量至/.bash_profile后,只运行一次,下次再创建project需要使用source ~/.bash_profile 命令。
(path设置可参考:http://www.flakor.cn/2014-09-14-714.html)
下图为django-admin所在目录:
6、查看manage.py帮助等:先cd到project目录再运行以下命令
如需查看manage.py中某个指令,可使用:
7、启动开发服务器--runserver:
在浏览器中输入网址:http://127.0.0.1:8000/,会看到项目已经在web server执行:
8、用startapp命令建立名为trips的app:
9、将新建的app添加到setting.py,让Django知道管理哪些apps(app之间有先后顺序),
打开mysite/setting.py,找到INSTALLED_APPS,进行如下修改:
二、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),如下图:
以上代码通过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/:
三、Templates
1、添加HTML/CSS&动态内容:
利用""" """多行字符串来保持HTML代码的缩进,使用datetime模块的datetime.now()获取当前时间,再利用format字符串格式化来将当前时间带入到current_time,现在网页显示效果如下:
此步骤是为了演示效果,实际使用时,通常把HTML/CSS代码独立出来,放在templates文件夹中,增加代码可读性以及方便调用。
2、创建templates文件夹:
首先在djangogirls/mysite下建立文件夹:
其次需要修改mysite文件夹中setting.py的TEMPLATES设置,将'DIRS'的[]修改为:
好让Django能够找到刚创建的templates文件夹:
然后在templates文件夹中创建hello_world.html,并将之前写在view function中的HTML代码复制到hello_world.html,现在mysite文件夹目录结构如下:
修改hello_world.html的代码:
注意html代码中的<em>{{current_time}}</em>,此处使用了Django Template语法。
最后,将view function hello_world修改如下:
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':
重新加载网页:
四、Models
本章学习如何利用Django Model定义数据库的结构(schema),并通过Django命令创建数据库(Database)、数据表(Table)以及字段(Field)。使用Django Model操作数据库的好处之一是,转换数据库很方便。
1、设置数据库:
此处使用默认的SQLite,打开mysite/setting.py,DATABASES部分如图所示:
ENGINE表示要使用的数据库引擎,NAME指数据库名称。
2、Django Models:
打开trips/models.py,创建一个Post类并定义属性,Django会依据这个类创建数据表以及表中的字段:
Django默认为每个Model加上一个id字段,并将id设置为primary key(主键),简称pk,让每一份数据都有独一无二的ID。
Post中的Field属性含义如下表:
3、同步数据库:
首先执行makemigrations命令:
这个命令会根据对Model的修改删除建立一个新的migration档案,让migrate命令执行时,可以依据此记录更新数据库。
然后用以下命令,让Django根据以上记录将model.py中的字段写入数据库:
结果应如图所示:
migrate命令会根据INSTALLED_APPS的设置,按照app的顺序新建或更新数据表,将model.py中的更新与数据库同步。
五、Admin
本章学习如何设置Django Admin,并使用Django管理后台,完成Post的新增、修改及删除。
1、设置管理后台--将Django Admin加入INSTALLED APPS:
将Django Admin加入mysite/setting中的INSTALLED APPS,Django已经默认开启后台管理功能,如下图:
2、设置管理后台--设置管理后台的URL:
为了可以从浏览器进入管理后台,需要设置对应的urls,此处将管理后台的网址设置为/admin/,确认mysite/urls.py的urlpatterns中包含下面的代码:
3、设置管理后台--创建superuser:
使用createsuperuser命令来创建管理员帐号:
注意:每个Django项目需要单独使用一个superuser帐号。
4、设置管理后台--注册Model class:
最后,要让Django知道,哪些Model需要管理后台,修改trip app里面的admin.py,并注册Post这个Model:
5、使用管理后台--进入管理后台:
重新运行web server,进入http://127.0.0.1:8000/admin/并登录:
AUTHENTICATION AND AUTHORIZATION区域可以管理使用者(User)和群组(Group);TRIPS区域中可以看到刚设置的Post Model,在这里可以执行Post的新增、修改、删除等功能。
可以试着新建一个Post:
需要填写的项目就是之前在model.py中创建的Post类中的属性。建立成功并保存后返回Post页面,会发现刚才创建的项目,显示为Post object:
Django通常以Post object来表示Post项目,项目多时不易辨认,可以通过def __str__修改Post的表示方式,修改trips/models.py:
重新加载网页,发现Post显示方式变成了显示标题:
六、使用Django ORM操作数据库
上一章使用Django Admin对Post进行新增、修改及删除,但实际应用中,会使用Django提供的QuerySet API进行数据库操作(CRUD),CRUD指Creat(新增)、Read(读取)、Update(修改)、Delete(删除)等常见的数据库操作。
1、使用Django shell:
此处使用IPython,可以使用pip3来安装IPython(之前安装过,这次没有在虚拟环境中安装,会警告,入下图),使用shell命令进入Django shell:
2、QuerySet API--Create:
3、QuerySet API--Read:
可以使用all()查看所有Post:
想查看部分数据时,可以使用get和filter:
get返回符合条件的唯一数据,如果找不到符合条件的数据或多条数据符合条件,将返回exception;filter返回符合条件数据的列表,如果找不到符合条件的数据将返回空列表。
4、QuerySet API--Update:
可以使用update修改一条或多条数据,首先先筛选出想要修改的数据:
将location修改为BeiJing:
5、QuerySet API--Delete:
可以使用delete将刚才修改的两条Post删除:
可以看到,现在只剩下后面两条Post。另外,删除前面的Post后,后面Post的id没有变化,还是之前的id:
注意:退出IPython重新进入后,想要操作数据库需要import要操作的Post,如重新进入IPython后未导入Post,会报错:NameError: name 'Post' is not defined,执行以下命令来导入:
七、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()中impport了需要用到的Model Post;通过Post.objects.all()取得所有posts,并传入home.html这个template。
3、创建首页--设置首页URL:
修改url.py,将首页指向home()这个view function:
4、Template tags--创建首页的Template并显示post_list:
首先,在template文件夹中新建home.html:
5、Template tags--显示Post中的数据:
观察网页,post_list是以list形式显示,为了显示每个post的数据,要使用for这个template tag:
现在修改home.html如下:
重新加载网页:
6、Template tags--显示照片:
网页现在显示的是照片网址,修改template home.html,让网页显示照片:
把{{ post.photo }}修改成:
7、Template tags--处理没有照片的post:
这里用到 {% if %} 判断,将home.html修改如下:
以上代码判断如果post.photo有值就显示照片,否则就使用CSS class photo-default处理。
8、Template tags--Template filter:
Template filter可以在变量显示之前进行一系列操作,使用方法:
<variable_name>:变量名称;<filter_name>:filter名称,如add、cut等;<fitter_arguments>:要传入filter的参数。
使用方法举例--变更时间的显示方式:这里使用的是date,可以将datetime类型的对象,以指定的时间格式输出,此处将created_at时间显示为年/月/日:
9、完整的HTML和CSS:
最终版home.html如下:
访问网页http://127.0.0.1:8000/,效果如下:
八、Dynamic URL
本章学习如何设置动态网址的URL conf,让每篇游记有单独的URL与页面。
1、建立单篇文章的View:
首先创建单篇文章所使用的view function,在trips/views.py中新增post_detail这个view:
以浏览网址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:
以上代码的url部分使用regex(正则表达式)提取部分URL作为参数,分析如下:
(?P<pk>\d+):\d代表一个阿拉伯数字,+代表一个以上,所以\d+就代表一个以上的阿拉伯数字,如0、99等;(?P<pk>)表示把这一串内容抓取出来,命名为pk,所以(?P<pk>\d+)表示:抓取一个以上阿拉伯数字并将抓取的内容命名为pk。
3、创建单篇文章页面的Template:
在templates中创建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 '<view_name>' %} ,根据在urls.py中的name值,找到对应的URL,也可以传入参数,如:
需要加入链接的地方有文章标题和Read More按钮,可以使用{% url %}来达成。
首先设置标题链接,打开home.html,找到:
将#修改为:
设置Read More链接,找到:
同上,将#修改为:
现在访问http://127.0.0.1:8000/,点击文章标题或Read More,可以访问文章详情页:
九、Deploy
本章学习如何将网站部署到服务器上,这里选择Heroku进行部署(Deploy)。
1、安装部署工具:
2、部署准备:
为了让sever了解部署时所需要的安装环境,要做以下准备:
requirements.txt:在djangogirls目录下,用以下命令将虚拟环境中的Python依赖包名称提取到txt文件中:
因为Heroku使用PostgreSQL数据库,要手动在requirements.txt最后一行加上psycopg2==2.6.1,最终的requirements.txt如下(版本号可能不同):
Procfile:创建一个Procfile文件并写入以下内容(没有任何扩展名):
这行代码是告诉Heroku如何启动我们的应用,Gunicorn是一个用Python开发的WSGI工具,可用来启动Django网站,启动网站命令如下:
runtime.txt:里面写入python-3.5.0,是为了让Heroku知道使用哪个版本的Python。
production_settings.py:前面章节通过修改settings.py来调整Django project的设置,但通常正式上线(production)的环境和开发/本机(development/local)环境有所不同,所以在mysite/mysite/下新建一个production_settings.py来存放部署时的设置:
wsgi.py:WSGI是Python定义网页程序和服务器沟通的界面,为了让Heroku的服务能够通过这个界面与我们的网站沟通,修改mysite/mysite/wsgi.py如下:
以上代码中,将dj_static导入,并在application上使用它,以协助我们部署static档案。
.gitignore:将不希望上传Git的文件名写入这个文件:
.gitignore是一个隐藏文件,可以使用以下代码进行显示及隐藏:
将true换成false即可隐藏。
最后djangogirls文件夹的数据结构如下:
3、Deploy to Heroku:
在开始部署前,先到Heroku官网注册帐号,并安装Heroku工具箱。
Step 1:登录Heroku
输入以下命令,并输入注册的邮箱帐号及密码即可登录:
Step 2:新增一个git repository
在djangogirls文件夹下新建一个git repository:
Step 3-1:新增Heroku app
现在要新增一个可以上传repository的地方:
create后面不加名字将创建随机名称的Heroku app,Heroku app不可以重名。
Step 3-2:指定已经存在的app
如之前创建过Heroku 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中列出的库:
报错 1:如遇到下面错误信息:
可通过下面的命令新增public key,然后重新git push:
报错 2:在修改git repository中的文件后直接执行git push命令,可能会有如下报错(通过heroku logs命令查看):
这时需要重新添加git repository后再执行git push:
Step 6:启动web process
之前创建的Procfile文件告诉Heroku启动时要执行的命令,现在用以下命令启动web process,并指定只需要一个instance:
Step 7:Django project初始化
Django现在已经成功启动,但还需要进行数据库初始化,利用heroku run可以执行命令:
并为新数据库创建一个superuser:
Step 8:在浏览器查看网站
可以通过heroku open命令查看部署到Heroku的网站。因为数据库和本地不同,之前的文章需要重新输入。
如果对网站进行了修改并想更新到Heroku,要先进行git commit再push到Heroku即可。