Django快速入门3留言板&管理页面

本章我们将首次使用数据库来构建基本的留言板应用,用户可以在其中发布和阅读短消息。我们将探索Django强大的内置管理界面,它提供了可视化的方式来对我们的数据进行修改。

强大的Django ORM(Object-Relational Mapper)内置了对多个数据库后端的支持。PostgreSQL、MySQL、MariaDB、Oracle或SQLite。这意味着可以在models.py文件中编写相同的Python代码,它将自动正确翻译成每个数据库。唯一需要的配置是更新我们config/settings.py文件中的DATABASES部分。

对于本地开发,Django默认使用SQLite,因为它是基于文件的,因此使用起来比其他数据库选项简单得多。

建立留言板应用

$ mkdir mb && cd mb
$ django-admin startproject config .
$ python manage.py startapp posts
$ vi config/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'posts', # new
]
$ python manage.py migrate

为了确保数据库反映项目的当前状态,你需要在每次更新模型时运行migrate(以及makemigrations)。

创建数据库模型

创建一个数据库模型,在那里我们可以存储和显示来自用户的帖子。Django的ORM会自动为我们把这个模型变成数据库表。

post/models.py文件

# posts/models.py
from django.db import models


class Post(models.Model):
    text = models.TextField()

我们已经创建了数据库模型,叫做Post,它有一个数据库字段text。我们还指定了它要容纳的内容类型,即TextField()。Django提供了许多支持常见内容类型的模型字段,如字符、日期、整数、电子邮件等等。

我们用makemigrations命令创建一个迁移文件。迁移文件为数据库模型的任何变化创建参考,这意味着我们可以跟踪变化,并在必要时调试错误。

$ python manage.py makemigrations posts
$ python manage.py migrate

如果运行 python manage.py makemigrations,就会为整个Django项目创建迁移文件。

Django管理

Django的杀手锏之一是其强大的内置管理界面,它提供了可视化的方式来与数据互动。Django最初是作为报纸CMS(Content Management System内容管理系统)而建立的。当时的想法是,记者们可以在管理编写和编辑他们的故事,而不需要接触 "代码"。随着时间的推移,内置的管理应用程序已经发展成为神奇的、开箱即用的工具,用于管理Django项目的各个方面。

要使用Django管员,我们首先需要创建超级用户。在你的命令行控制台中,输入python manage.py createsuperuser,并对提示的用户名、电子邮件和密码做出回应。

$ python manage.py createsuperuser

用python manage.py runserver重启Django服务器,在你的网页浏览器中进入http://127.0.0.1:8000/admin/。你应该看到管理员的登录界面。

但是我们的帖子没有显示在管理主页面上!必须更新一个应用程序的admin.py文件,使其出现在管理员中。

在你的文本编辑器中打开post/admin.py,添加以下代码,以便显示Post模型。

# posts/admin.py
from django.contrib import admin

from .models import Post

admin.site.register(Post)

Django现在知道它应该在管理页面上显示我们的post应用程序和它的数据库模型Post。如果你刷新你的浏览器,你会看到它出现了。

点击帖子对面的+添加按钮,在文本表格字段中输入你自己的内容。

然后点击 "保存 "按钮,这将重定向到主帖子页面。然而,如果你仔细观察,就会发现问题:新条目被称为 "Post object",这不是很好的描述!

让我们来改变它。在 posts/models.py 文件中,添加一个新的函数 str,如下所示。

# posts/models.py
from django.db import models


class Post(models.Model):
    text = models.TextField()

    def __str__(self):
        return self.text[:50]

这将显示文本字段的前50个字符。

视图/模板/URLs

现在我们想列出我们数据库模型的内容,Django配备了基于通用类的ListView。

在post/views.py文件中输入下面的Python代码。

# posts/views.py
from django.views.generic import ListView
from .models import Post


class HomePageView(ListView):
    model = Post
    template_name = 'home.html'

增加模板

$ mkdir templates
$ vi templates/home.html
<!-- templates/home.html -->
<h1>Message board homepage</h1>
<ul>
  {% for post in object_list %}
    <li>{{ post.text }}</li>
  {% endfor %}
</ul>

最后一步是设置我们的URLConfs。
config/urls.py文件

# config/urls.py
from django.contrib import admin
from django.urls import path, include # new

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('posts.urls')), # new
]

然后在post应用程序中创建urls.py文件。

# posts/urls.py
from django.urls import path
from .views import HomePageView

urlpatterns = [
    path('', HomePageView.as_view(), name='home'),
]

用python manage.py runserver重新启动服务器,并导航到我们的主页,现在它列出了我们的留言板帖子。

测试

以前,我们只测试静态页面,所以我们使用SimpleTestCase。但现在有数据库,需要使用TestCase。我们不需要在我们的实际数据库上运行测试,而是可以建立一个单独的测试数据库,用样本数据填充,然后针对它进行测试,这肯定是更安全、更快的方法。

# 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): # new

    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')
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,230评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,261评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,089评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,542评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,542评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,544评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,922评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,578评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,816评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,576评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,658评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,359评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,920评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,859评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,381评论 2 342

推荐阅读更多精彩内容