原版书名:《Django 2.1 Tutorial : Build a Travel Blog with GoormIDE and Bootstrap 4 (Tutorial Project)》
作者:Hojun Lee、 Suwon Choi
出版时间:2018-08
演示地址:https://tutorialdjango-ircmu.run.goorm.io/
源码地址:https://github.com/wenguonideshou/tutorialdjango
这本书适合谁
这本书的目标读者是想使用django编程的程序员。django是python语言里非常流行的框架。希望这是个提升你的web开发技能的好机会。
关于这本书
这本书将会教你使用django开发简单旅游博客,并不学习django开发的详细细节,而是主要关注于手把手的开发简单web项目。
如果你跟着操作,你将学会开发django web项目,你可以在上面的源码地址下载源码和模板。
本书的前端编程部分使用bootstrap 4。
学完教程后
学完本书后,你将学会排错,并记录解决办法,而且你将能开发实际的web项目。
如果你对python其他方面感兴趣,你可能还想学习数据分析、数据可视化或人工智能。
第一章 在Goorm IDE安装环境
1.1 介绍
django是基于python开发的免费开源的web框架,在Instagram、NASA、Disqus等大公司应用广泛。
框架是利用诸多现成的组件使得开发web应用更快更容易的支持结构。
django在2005年做为免费开源的框架出现,django2.0在2017年12月发布,目前在韩国还没有关于django2.0的书籍。
为了理解网站开发的全部过程,本书中我们将开发简单博客。
如果你想了解django的更多信息,建议参考django官方网站 https://www.djangoproject.com ,官方主页提供django介绍、下载和支持文档。
PDF文档下载地址 https://media.readthedocs.org/pdf/django/2.0.x/django.pdf
1.2 安装django和环境配置
下图描述互联网的工作原理,这是你在浏览器输入google.com后互联网的运行流程。
我们即将开发的网站也会是安装这样的流程运行。
我们将使用不同的编程语言和框架如HTML、CSS、JavaScript、Python、Bootstrap和django。
1)你在浏览器输入google.com
2)浏览器获取到你输入的域名
3)浏览器从DNS服务器获取到域名对应的IP 216.58.221.164
4)浏览器向Google服务器发起首页请求
5)浏览器渲染服务器返回的响应,展现给你
我们将使用GoormIDE的云服务,操作系统是基于Linux的Ubuntu 14。
过去大家大部分使用图形化界面环境比如Windows,因此纯黑界面的Linux命令行环境可能对你来说比较陌生。
Linux系统占有全世界服务器操作系统至少90%的市场。这就是我们推荐使用Linux系统的原因。
对比下3种不同的云服务类型
SaaS(Software as a Service):SaaS是软件的开发、管理、部署都交给第三方,不需要关心技术问题,可以拿来即用,是用户体验最好的
PaaS(Platform as a Service):PaaS提供软件部署平台,抽象掉了硬件和操作系统细节,可以无缝地扩展。开发者只需要关注自己的业务逻辑,不需要关注底层
IaaS(Infrastructure as a Service):IaaS是云服务的最底层,主要提供一些基础资源,主要是专业人士使用
我相信你选择本书是因为被python强大的库、直观、优秀的可扩展性吸引。
现在python已成为世界上最流行的编程语言之一。
关于框架呢?下图是python官方wiki上关于python不同框架的描述。
除django外,还有其他流行的框架比如Flask。django是全栈web框架,而Flask是轻量、可扩展的。
从下面的框架中做出选择,没有绝对的正确和错误,这完全取决于你的项目。
1.2使用IDE配置环境
下面开始设置Goorm IDE环境,注意图片中的红框,官网 https://ide.goorm.io ,点击Sign Up注册账号,免费账号完全够用,可以创建5个容器。
注册完成后会自动登录Dashboard,或者在首页点击Dashboard。
在Dashboard页面有个看起来像设置电脑的容器,点击Create a new container,新版goorm需要填写申请理由然后人工审核通过后才能新建容器,内容就填写学习django web开发。
审核通过后,再次点击Create a new container,Source from选择Template,Name栏输入tutorialdjango,Description栏输入create a travel blog in django,software stack选择Python,点击Create
你将看到容器很快创建完成,并提示是否运行容器,点击Run进入容器
容器加载过程中通常会有代码提示或提到名人
下图是容器成功加载后的界面
①处是文件夹结构,在右上角有个刷新按钮,如果你新建或更新某些文件/文件夹但是在①看不见,就点击刷新按钮
②显示.txt .html .py等文件的内容
③协作、聊天窗口,我们不会使用到它
④命令行窗口,大部分命令在这里输入
点击Project - Running URL and Port,下图的红色方框是以后从外部访问的URL地址
提示:如果你没设置域名,在URL处输入域名,然后设置PORT为80
首先就是设计网站界面,本书不包括此步骤,如果想了解详情请阅读书籍《Bootstrap Tutorial: Learn how to create Travel Blog using Bootstrap》
我们看下站点结构:
主页 https://用户域名.run.Goorm.io
主页,网站介绍,Google地图API,最新发布
模板:index.html
博客列表 https://用户域名.run.Goorm.io/blog/
点击blog会跳转到主页,展现博客列表
模板:blog.html
文章详情 https://用户域名.run.Goorm.io/blog/文章ID
在列表页点击文章后跳转
模板:contens.html
下面是项目完成后的网站主页预览图,我们任意新建了一些文章
下面是博客列表页
下面是文章详情页,我们也任意填充了一些内容
现在开始开发,在④命令行窗口按步骤输入下面的命令
python --version # 检查python版本,是3.6.5 mkdir mysite # 创建名为mysite的文件夹 cd mysite # 进入mysite目录 apt-get install python-virtualenv # 安装虚拟环境所需要的包 virtualenv myvenv # 基于python3.6.5创建虚拟环境 source myvenv/bin/activate # 激活虚拟环境,注意:每次使用云容器都应该运行此命令激活虚拟环境
现在命令行最前面有(myenv)标志,说明已进入虚拟环境
安装django,创建项目
pip3 install django==2.0.6 # 安装django django-admin startproject tutorialdjango . # 在当前目录新建项目 python manage.py migrate # 稍后解释,简而言之,在数据库中新建表结构
一定要注意django-admin startproject后面的.
如果你创建的容器名称不是tutorialdjango,命令修改为django-admin startproject xxx,其中xxx是你的容器名称
现在打开左边面板,修改tutorialdjango目录的settings.py,第28改行为ALLOW_HOSTS = ['*'] 允许任意用户访问,如图所示
修改后按Ctrl+S保存生效,然后在命令行输入下面的命令
python manage.py runserver 0:80
点击Project - Running URL and Port
点击红框中的域名,浏览器会打开如图所示的页面
第二章 创建主页
使用django可以同时创建和组装多个应用,因为我们开发的是简单项目,现在我们只新建1个叫main的应用,在命令行窗口Ctrl+C停止运行上面的项目,输入命令:
python manage.py startapp main
在settings.py找到INSTALLED_APPS在最下面添加1行,注册main应用
注意:在'main'后面有个,
在项目下的urls.py添加内容视图函数和URL的映射
from main.views import index
意思是导入main目录下的views.py中的index函数,现在在views.py还没定义index函数,所以会报错,添加一行
path('', index)
意思是django会重定向任何访问 http://用户域名/ 到index函数,下面将连接index函数和index.html模板
文件位于 mysite/tutorialdjango/urls.py
现在打开mysite> main> views.py新建index函数,可以看到 调用此函数时它将会返回render渲染main/index.html模板
文件位于 mysite/main/urls.py
新建myiste/main/templates/main/index.html目录和文件,然后粘贴以下代码:
<html> <head> <title>Django!</title> </head> <body> <h2>Test!</h2> </body> </html>
启动web服务,看看网站发生了什么变化
python manage.py runserver 0:80
在域名后面添加/admin然后回车即可访问管理后台,可以在后台发布、编辑、删除文章,还可以管理用户。
但是现在还不能登录,因为没有创建管理员账号。为了安全考虑,建议在web应用中不要对外开放管理后台。
接下来将展示如何在主页加载图片,django不支持HTML和CSS中的相对目录。
在mysite目录下新建static文件夹,用来存储静态文件。
上传图片
如果在左边面板没找到图片,点击刷新标志即可
如图所示 在settings.py定义静态文件目录列表,注意在代码最后有个,
STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), )
打开index.html输入下列代码调用静态文件,{% %}语法意思是调用模板标签
更多django模板语法请访问 https://docs.djangoproject.com/en/2.0/ref/templates/builtins/
<html> <head> <title>Django!</title> </head> <body> <h2>Test!</h2> {% load staticfiles %} <img src="{% static 'bluemountain.jpg' %}"> </body> </html>
如果web服务器没有运行,在命令行输入python manage.py runserver 0:80 ,点击Project - Running URL and Port菜单,点击域名,可以正常访问
现在项目结构如下图所示,红色方框的文件是刚修改过的文件
django把MVC模式叫做MTV模式,虽然术语改变,但是本质是相同的。下图演示了django的运行流程。
CRUD分别代表增、查、改、删
第三章 创建列表页
新建包括所有文章的列表页,首先编辑tutorialdjango/urls.py和tutorialdjango/views.py
from main.views import index, blog path('blog/', blog)
def blog(request): return render(request, 'main/blog.html')
新建mysite/main/templates/main/blog.html文件,输入以下代码
<html> <head> <title>Django!</title> </head> <body> <h2>Blog Page!</h2> </body> </html>
运行web服务器,浏览器打开 https://用户域名/blog/ ,可以正常访问
现在为每篇文章新建内容,首先需要创建文章模型,包括postname和contens字段,在myiste/main/models.py输入
class Post(models.Model): postname = models.CharField(max_length=50) contents = models.TextField()
要在数据库中新建模型对应的表结构,按Ctrl+C停止web服务器,然后输入下面的迁移命令
python manage.py makemigrations main python manage.py migrate
现在打开main/admin.py导入模型,修改管理后台界面
from .models import Post admin.site.register(Post)
现在创建超级管理员账户,超级管理员能删除、编辑、保存文章,还能管理其他用户。 在命令行窗口输入
python manage.py createsuperuser
为了安全考虑,在命令行输入密码的时候是不可见的。
再开启web服务器,能看见登录界面了吧。
输入创建的超级管理员用户名和密码登录,进入后台可以试下新建文章
点击SAVE后,刚才输入的标题并没有显示,而是只显示了Post object(1)。这是因为没有定义模型的显示名为postname。
编辑main/models.py输入
def __str__(self): return self.postname
刷新后台页面,现在可以看到刚才发布的文章标题,现在随便创建一些文章,稍后会删除。
这里我创建了3篇文章,现在准备在列表页展现这些文章,修改main/views.py
from .models import Post postlist = Post.objects.all() {'postlist': postlist}
修改blog.html模板在<h2>下面新增代码
<table> {% for list in postlist %} <tr> <td>{{list.postname}}</td> <td>{{list.contents}}</td> </tr> {% endfor %} </table>
这里使用{}模板标签从数据库获取所有数据
更多关于Django文档请访问 https://docs.djangoproject.com/en/2.0/
模板语言文档请访问 https://docs.djangoproject.com/en/2.0/ref/templates/language/
现在使用F12查看网页源代码,是看不到模板语言的,因为是在django内部渲染成HTML再展现给访客
第四章 新建详情页
任何时候你返回该项目,都需要运行下面的命令确保运行的是虚拟环境的python而不是系统自带的python
在使用虚拟环境的情况下,命令行最前面有(myvenv)标志
root@Goorm:/workspace/container name# cd mysite
root@Goorm:/workspace/container name/mysite# source myvenv/bin/activate
(myvenv)root@Goorm:/workspace/container name/mysite#
如果你在没有进入虚拟环境的情况下运行了以下命令,此时最好的解决办法就是删除容器并重建容器。
最前面是否有(myvenv)标志非常重要,因为他代表的是完全不同的运行环境!
现在创建详情页,展示每一篇文章。修改tutorialdjango/urls.py新增以下代码
from main.views import index, blog, postdetails path('blog/<int:pk>', postdetails),
修改main/views.py,新增以下代码
def postdetails(request, pk): postlist = Post.objects.get(pk=pk) return render(request, 'main/postdetails.html', {'postlist': postlist})
如下图所示,在templates文件夹有3个模板文件,现在这个是最后的模板(在第七章将会使用bootstrap美化模板)
新建templates/main/postdetails.html,输入
<html> <head> <title>Django!</title> </head> <body> <h2>Postdetails Page!</h2> <p>{{postlist.postname}}</p> <p>{{postlist.contents}}</p> </body> </html>
在URL最后添加文章数字编号,页面如图所示
使用onclick事件实现 在博客列表页点击文章标题或者内容进入文章详情页,编辑templates/main/blog.html
<tr onclick="location.href='/blog/{{list.pk}}'">
点击后
在详情页新建返回列表页的按钮,在postdetails.html添加带超链接的标签<a>
<a href='/blog/'>List(Go back)</a>
编辑main/models.py,新增可以上传图片的ImageField
mainphoto = models.ImageField(blank=True, null=True)
由于要上传图片,所以需要安装叫Pillow的图片处理库
pip3 install pillow # 上面修改了模型,所以需要迁移模型到数据库 python manage.py makemigrations python manage.py migrate python manage.py runserver 0:80
修改settings.py,设置上传文件的保存目录MEDIA_ROOT和访客访问的URL,如果不设置MEDIA_ROOT,文件将会上传到mysite目录下
现在在后台新建5篇文章,每篇文章上传1张图片
最开始上传名为jeju的图片,点击文章查看文件图片是否上传成功
点击图片文件名,浏览器弹出新页面 报错提示文件不存在,但是刚刚我们明明已经上传了!
还差一步,在urls.py设置图片URL
from django.conf.urls.static import static from django.conf import settings urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
现在可以刷新页面可以看到图片了
修改postdetails.html添加代码,注意红框内的域名改成你自己的
{% if postlist.mainphoto %} <img src='{{postlist.mainphoto.url}}'> {% endif %}
django官方文档中相关说明
现在可以在详情页看到图片了
第五章 增加评论框和标签
现在增加评论功能,我准备使用叫Disqus的插件。
也可以使用pip3 install django-disqus安装该扩展,但我打算使用另一种方式安装。
打开 https://disqus.com/ 点击Get Started
输入用户名、邮箱等注册
注册成功后先去邮箱收件箱 查收验证邮件,验证邮箱,然后点击I want to install Disqus on my site
输入网站名称、网站类型、语言,点击Create Site
选择套餐,当然是Basic啦。点击Subscribe Now
现在选择平台,点击最后的I don't see my platform listed, install manually with Universal Code
复制①里面的代码,点击Configure
点击Complete Setup
编辑postdetails.html在</body>标签前粘贴代码
刷新详情页,可以在页面最下面看到评论框
修改模型增加发布时间字段、编辑时间字段
publishDate = models.DateTimeField(blank=True, null=True) modifiedDate = models.DateTimeField(blank=True, null=True)
迁移模型
python manage.py makemigrations python manage.py migrate
在后台可以看到新增的字段
修改所有文章,并修改blog.html模板,增加下面这行
<td>{{list.modifiedDate}}</td>
添加过编辑时间字段的文章都能在网页上显示编辑时间
安装django-taggit为文章添加标签,还可以利用标签来查找具有相同标签的文章
pip3 install django-taggit
修改models.py添加tag字段
from taggit.managers import TaggableManager tag = TaggableManager(blank=True)
编辑settings.py,在INSTALLED_APPS添加'taggit',
迁移模型
python manage.py makemigrations python manage.py migrate
在后台确认文章编辑界面底部是否有标签选项,把旅行过的国家作为标签
输入标签,点击SAVE保存
修改postdetails.html添加以下代码
<p>{{postlist.tag.names}}</p>
在详情页可以看到Queryset类型的标签
使用for循环语句可以展现所有的标签,我暂时只使用1个标签所以用{{post.tag.names.0}}
现在标签是字符串类型了
第六章 使用bootstrap美化模板以及部署
可以把bootstrap看成花最少的精力快速获得想要的结果的包罗万象的前端web框架。
不管是超大屏幕还是手机端,bootstrap都为用户体验量身定制,也叫响应式设计。
bootstrap自带HTML、CSS、表单、按钮、表格、导航栏。
bootstrap3中能用的标签大部分在bootstrap4也能使用,但是4相较于3变化也不小,所以你需要了解下新版本的bootstrap。
可以在 https://www.w3schools.com/bootstrap4 找到bootstrap4的入门教程。
更多信息请访问官方网站 https://getbootstrap.com/docs/4.1/content/reboot/
可以在 https://getbootstrap.com/ 下载bootstrap4(在本书中不需要下载)
bootstrap默认模板使用CDN(内容分发网络),CDN的好处是无需下载文件,在全球访问速度都很不错
如果想使用最新版本的CDN,在Google搜索"bootstrap cdn"然后访问 https://www.bootstrapcdn.com 获取,最新版本是4
在001.html的<body></body>标签内有调用CDN的<script></script>标签,下图中的红框是模板中用来填充内容的代码
利用bootstrap的网格系统可以快速方便的建立响应式布局,整个页面的一行中可以有最多12列,如果不想使用全部12列 可以把列合并为更宽的列。
如下图所示,在<body></body>标签之间输入代码后,保存为002.html并用浏览器打开
红框代表在一行中定义的网格,每4小列分组为1个中型列,所以能看到3列
003.html把.col-md-4类和.col-md-6类的网格进行对比,效果一目了然
在官方网站可以看到,列也可以拆分
如果想在网格系统中使用所有的12列占满屏幕,使用.container-fluid类。
还可以把.no-gutters类添加到.row类,以消除列之间的外边距和内边距。
下面是官方网站对网格系统的描述,nestable意思是可以分割列。常用的是md类。
如果使用了偏移列,列的位置将会浮动,有许多方法设置外边距,不过常用的是偏移列和弹性盒子对列排序。下图的003.html只使用了偏移列。
现在解压templates.zip后,可以看到index.html,blog.html和blogdetails.html。
用浏览器打开index.html可以看到含有标记的地图。
每篇文章都需要坐标以在地图上做标记。
下图index001.html里的LatLng指的是纬度和精度。
在模型中添加经纬度字段
Lat = models.FloatField(null=True) Lng = models.FloatField(null=True)
官方文档提供blank和null的解释和区别:https://docs.djangoproject.com/en/2.0/ref/models/fields/#django.db.models.FloatField
迁移模型,重新运行web服务器
python manage.py makemigrations python manage.py migrate python manage.py runserver 0:80
可以在后台文章编辑页面看到地理坐标类型的经纬度字段。
如果忘记了后台用户名密码,可以在命令行执行python manage.py changepassword admin修改admin用户的密码。
给每篇文章填充经纬度数据
bluemountain 照片,经纬度(-33.3493206,149.7360613)
jejucityhall 照片,经纬度(33.499597,126.5290653)
perth 照片,经纬度(-32.0388312,115.4010747)
sydney 照片,经纬度(-33.8567844,151.213108)
tasmania 照片,经纬度(-42.200633, 146.643736)
然后从lorem ipsum网站生成虚假内容然后从本地templates/img文件夹上传照片。
lorem ipsum网站:https://lipsum.com/
现在删除其他数据,只留下下面5条。
编辑views.py在index函数里添加以下代码,才能在首页使用postlist变量
postlist = Post.objects.all()
从index_002.html复制全部代码,粘贴到index.html。这2个文件唯一不同的地方如下图所示。
现在刷新首页,可以看到坐标标记,但是照片是裂开的。
接下来用{% %}和{{}}语法把每篇文章的照片放到红色方框的Infowindow(信息窗口,地图专用术语)中。
点击照片后,跳转到文章详情页。
把index_003.html的所有代码复制到index.html中,记得把其中的域名改成你自己的域名。
下图显示的是2个文件之间的区别,左边是index.html右边是index_003.html。
打开本地的templates/blog.html,修改blog.html的第161到180行的代码,找到<a href=""></a>然后把红框位置换成你的自己的域名。
复制全部代码,粘贴到云服务的blog.html。
现在访问 https://你的域名/blog/ ,点击每张图片都会跳转到文章详情页。
打开本地的templates/blogdetails.html,修改第147到166行,找到<a href=""></a>标签,把红框的域名换成你自己的域名。
然后复制所有代码,粘贴到云服务里面的postdetails.html。
现在访问 https://你的域名/blog/文章ID ,可以看到漂亮的带评论框的详情页。
虽然本书中并没有用到模板继承,但是在实际的django web项目开发中会经常用到模板继承。
一般是新建含有头部、菜单、底部等的母版,然后在其他所有模板中继承此模板。
下图是模板继承的简单例子。year_archive.html继承base.html。
在GoormIDE,Always On(永远在线)选项仅供付费用户。
如果是付费用户,当点击Always On,容器的绿色在线状态将会被点亮,访客可以在任意时间访问旅游博客。
负责只能在Dashboard点击Run后容器才能运行,网站才能访问。
点击图片中的红框地方,查看更多详细选项。
部署
点击Configure进入详细配置页面,点击+Add添加你自己购买的域名和端口,或者使用GoormIDE赠送的域名也可以。
在Setting下面的Init script处点击Set,然后输入容器初始化命令,我经常使用下面2行命令:
source /workspace/容器名称/mysite/myvenv/bin/activate python3 /workspace/容器名称/mysite/manage.py runserver 0:80
输入完成后,点击下面的Stop停止容器,再点击右上角的Run
现在访问域名,测试网站完全正常运行。如果正常,说明上面的初始化脚本正常运行。
第七章 总结
django是python语言中快速开发web项目的框架,大部分功能都已经自动化,而且官方文档也很详尽。
阅读官方文档后,不用再考虑其他文档了。
现在我们使用django创建了简单的博客。
但是这仅仅使用了django的一小部分功能,如果想使用更多更强大的功能,推荐阅读官方文档。
下面是django的结构图,我画图简单总结之前我们做的所有步骤。你可以对照检查下是否有步骤遗漏。
注意:我们没有使用到表单功能
Django
urls.py
下图是我们之前所有操作的流程图。
最开始修改的是urls.py,urls.py根据特定的URL规则调用视图函数 。
views.py
在urls.py定义URL规则后,创建与URL相关联的视图函数。视图函数包括页面逻辑。
models.py
模型中的类变量代表数据库中的字段。需要执行迁移以保证数据库和模型结构同步。
templates
模板就是简单的文本文件,可以是任何基于文本的格式(html,csv等),模板展示的是页面设计界面。
译者注:全文到此结束。作者的模板做的很粗糙,页面中的很多超链接是死链。毕竟这只是个入门教程。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。