Django for beginner:用Django2.0部署并上线Message Board应用

in #python7 years ago

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命令才是实际执行这些命令。

注意,在makemigrationsmigrate后面并不一定要加上一个名字,比如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/ , 可以看到服务端的登录屏幕:
image

但是这里并没有看到我们的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!
image

增加新的贴文

基本上已经完成了。回到后台http://127.0.0.1:8000/admin/ , 随便新增几个贴文。再回来看!
image

完美!现在,提交代码到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/

亲自动手做成的第一个网站。

Sort:  

程序员真的牛!可惜我看不懂。