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

Message board homepage

    {% for post in object_list %}
  • {{ post.text }}
  • {% endfor %}

最后一步是设置我们的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')

你可能感兴趣的:(Django快速入门3留言板&管理页面)