Django for beginner:用Django2.0部署并上线Message Board应用
Chapter 4:Message Board App
本章学习日期: 2018年3月6日
章节学习地址:https://djangoforbeginners.com/message-board/
本章学习内容:
本章介绍了如何用Django创建一个数据库驱动的应用,并且使用Django的admin进行相关数据库的管理与操作。最后,还带着我们过了一遍测试和部署上线。
本章用的数据库是Django内置的SQLite。
初步设置
还是之前的套路,配置虚拟环境、创建项目、更新相关配置文件。
- 创建
mb
文件夹 pipenv install django
django-admin.py startproject mb_project .
创建新项目mb_project
python manage.py startapp posts
创建新app——posts
- 更新
settings.py
文件
# mb_project/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'posts',
]
- 执行
migrate
,根据Django的初始设置创建数据库
$ python manage.py migrate
这时候,文件夹里会出现一个db.sqlite3
文件。
创建数据库模型(database model)
首要任务是创建一个数据库模型,用来存储和展示来自用户的贴文。Django会将这一模型转换成数据库表。
在posts/models.py
文件更新内容如下:
# posts/models.py
from django.db import models
class Post(models.Model):
text = models.TextField()
Django导入了一个models
模块,用来创建新的数据库模型。这里我们需要一个文本类的模型,所以导入的是models.TextField()
。其他的内容类型还有日期、整数、邮箱等等。
激活模型
$ python manage.py makemigrations posts
$ python manage.py migrate posts
无论是创建新模型还是修改现有模型,我们都要通过2个步骤来更新Django。
makemigrations
命令会为INSTALLED_APPS
里的预先导入应用生成一个SQL命令。这一步并不会执行这些命令,仅仅记录。
migrate
命令才是实际执行这些命令。
注意,在makemigrations
和migrate
后面并不一定要加上一个名字,比如posts
。这样做的好处是,以后如果需要往前看,可以看到每次具体的migration记录。
Django Admin
Django的后台十分强大,使用前需要创建一个可以登录的superuser
。
$ python manage.py createsuperuser
Username (leave blank to use 'larus'): larus
Email:
Password:
Password (again):
Superuser created successfully.
注意:输入密码的时候,出于安全考虑,命令行控制器并不会展示密码。
python manage.py runserver
重启Django服务,然后前往http://127.0.0.1:8000/admin/ , 可以看到服务端的登录屏幕:
但是这里并没有看到我们的posts
应用。打开posts/admin.py
文件,编辑结果如下:
# posts/admin.py
from django.contrib import admin
from .models import Post
admin.site.register(Post)
我们必须主动告诉Django在后台admin里展示什么内容。刷新页面,即可看到更新后的Posts模型。
另外,为了让后台里可以看到新增的post内容名称,还要更新一下posts/models.py
文件。
# posts/models.py
from django.db import models
class Post(models.Model):
text = models.Textfield()
def __str__(self):
""" A String representation of the model."""
return self.text[:50]
Views/Templates/Urls
重头戏来了。为了在主页看到我们的数据库内容,我们需要重写一下views,templates和URLConfs。
首先是view。之前我们用的是内置的TemplateView,用来展示模板。现在,我们要用ListView来展示数据库模型。
在posts/views.py
文件里编辑如下:
# posts/views.py
from django.views.generic import ListView
from .models import Post
class HomePageView(ListView):
model = Post
template_name = 'home.html'
ListView会返回一个叫做object_list
的对象,我们将要在模板里使用。
接下来是模板。创建模板文件夹和模板文件。
$ mkdir templates
$ touch templates/home.html
然后更新settings.py
里的'DIRS'Field,让Django知道模板在什么位置。
# settings.py
TEMPLATES = [
{
...
'DIRS':[os.path.join(BASE_DIR,'templates')],
...
},
]
在模板文件home.html
更新以下内容:
(html comment removed: templates/home.html )
<h1>Message board homepage</h1>
<ul>
{% for post in obejct_list %}
<li>{{ post }}</li>
{% endfor %}
</ul>
最后一步是配置URLconfs,先从项目级的urls.py
开始。
# mb_project/urls.py
from django.contrib import admin
from django.urls import path , include
urlpatterns = [
path('admin', admin.site.urls),
path('', include('posts.urls')),
]
然后创建一个应用级的urls.py
文件,并更新如下:
# posts/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.HomePageView.as_view(), name='home'),
]
重启服务,可以在http://127.0.0.1:8000/ 看到信息板上已经有了我们的Hello World!
增加新的贴文
基本上已经完成了。回到后台http://127.0.0.1:8000/admin/ , 随便新增几个贴文。再回来看!
完美!现在,提交代码到git
。
$ git init
$ git add -A
$ git commit -m 'initial commit'
测试
又来到我目前最头疼的环节——测试了。这部分我还不是很熟悉,就先贴代码,完成一遍,后面再细细理解。
# posts/tests.py
from django.test import TestCase
from django.urls import reverse
from .models import Post
class PostModelTest(TestCase):
def setUp(self):
Post.objects.create(text='just a test')
def test_text_content(self):
post=Post.objects.get(id=1)
expected_object_name = f'{post.text}'
self.assertEqual(expected_object_name, 'just a test')
class HomePageViewTest(TestCase):
def setUp(self):
Post.objects.create(text='this is another test')
def test_view_url_exists_at_proper_location(self):
resp = self.client.get('/')
self.assertEqual(resp.status_code, 200)
def test_view_url_by_name(self):
resp = self.client.get(reverse('home'))
self.assertEqual(resp.status_code, 200)
def test_view_uses_correct_template(self):
resp = self.client.get(reverse('home'))
self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp, 'home.html')
一共有两个测试。一个是对Post数据模型的测试,一个是对主页展示内容的测试。
执行代码,查看测试结果:
(mb) $ python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 4 tests in 0.036s
OK
Destroying test database for alias 'default'...
测试完,别忘记再次提交代码。
$ git add -A
$ git commit -m "added tests"
Bitbucket
参照之前的教程,将代码提交到Bitbucket远程repository。
Heroku配置
这次的项目用到了数据库,我们部署到线上:
- 更新
Pipfile.lock
# Pipfile
[requires]
python_version = "3.6"
- 新的
Procfile
$ pipenv lock
创建一个Procfile
文件,告诉Heroku如何运行远程服务器。
web: gunicorn mb_proejct.wsgi --log-file -
- 导入
gunicorn
$ pipenv install gunicorn
- 更新
settings.py
# mb_project/settings.py
ALLOWED_HOSTS = ['*']
完成,再次提交代码。
$ git status
$ git add -A
$ git commit -m "New updates for Heroku deployment"
$ git push -u origin master
###部署Heroku
$ heroku login
$ heroku create
$ heroku git:remote -a agile-inlet-25811 # agile-inlet-25811 是Heroku生成的名字
$ heroku config:set DISABLE_COLLECTSTATIC=1 # Heroku会忽视静态文件
$ git push heroku master
$ heroku ps:scale web=1
$ heroku open
此时,部署的每一步含义大致了解就可以了,照葫芦画瓢!
最后一步的heroku open
会调用默认浏览器,直接打开我们最终成果所在的地址,我的是https://boiling-fortress-99967.herokuapp.com/ 。
亲自动手做成的第一个网站。
程序员真的牛!可惜我看不懂。