网站搜索

如何使用 Django 框架创建适合移动设备的 Web 应用程序 - 第 3 部分


“本文已使用最新版本的 Django 进行修订和更新 – 2016 年 5 月”

在本系列的第 1 部分中,您学习了如何在虚拟环境中安装和配置 Django,并创建了第一个项目的框架。

然后,在第 2 部分中,我们为 Post 对象创建了一个应用程序和一个模型,随后将其迁移到数据库中。最后,我们向您展示了如何将新创建的应用程序集成到 Django 管理用户界面。

这些文章是 Django 系列的一部分:

使用虚拟环境安装和配置 Django Web 框架 – 第 1 部分

回顾 Python 基础知识并使用 Django 创建您的第一个 Web 应用程序 – 第 2 部分

在本最终指南中,我们将讨论如何使用 UI 访问应用程序以及如何使其适合所有类型的设备。也就是说,让我们开始吧。

通过 Django 管理界面创建对象

要创建 Post 类型的对象(请记住,这是我们在本系列的第 2 部分中定义的模型),我们将使用 Django 管理界面。

通过从外部 myfirstdjangoproject 目录运行以下命令,确保 Django 内置 Web 服务器在端口 8000(或您选择的其他端口)上运行:


cd ~/myfirstdjangoenv/myfirstdjangoproject
python manage.py runserver 0.0.0.0:8000

现在打开您的网络浏览器并指向 http://ip-address:8000/admin,然后使用您在上一篇文章中设置的凭据登录并开始撰写帖子(同样,将创建一个 Post 类型的对象并将关联数据插入到底层数据库中):

重复该过程 2 或 3 次:

创建几个帖子后,让我们看看需要做什么才能使用网络浏览器显示它们。

我们的初步看法

我们的第一个视图 (~/myfirstdjangoenv/myfirstdjangoproject/myblog/views.py) 将负责过滤所有 Post 对象并返回那些 whenPublished 值的对象 小于或等于当前日期和时间 (whenPublished__lte=timezone.now())whenPublished 降序排序,这与“ 最新的第一个“。

这些对象被保存到一个名为 posts 的变量中,并返回(标识为 allposts)以嵌入到 HTML 中,我们将在下一节中看到:


from django.shortcuts import render
from .models import Post
from django.utils import timezone
def posts(request):
        posts = Post.objects.filter(whenPublished__lte=timezone.now()).order_by('-whenPublished')
        return render(request, 'myblog/posts.html', {'allposts': posts})

最后,上面 whenPublished__lte 中的双下划线用于将数据库字段 (whenPublished) 与过滤器或操作分开(lte=less 小于或相等)。

定义了初始视图后,我们就可以处理关联的模板了。

为我们的第一个项目创建模板

按照上一节中给出的指令和路径,我们将把初始模板存储在 myblog/templates/myblog 中。这意味着您需要创建一个名为 templates 的目录和一个名为 myblog 的子目录:


cd ~/myfirstdjangoenv/myfirstdjangoproject/myblog
mkdir -p templates/myblog

我们将调用模板 posts.html 并在其中插入以下代码。您会注意到,我们添加了对 jQuery、Bootstrap、FontAwesome 和 Google 字体的在线引用。

此外,我们已将 Python 代码括在 HTML 内的大括号内。请注意,对于 Post 类型的每个对象,我们将显示其标题、发布日期和作者,最后是其文本。最后,在红色中,您将看到我们对通过 myblog/views.py 返回的对象进行了引用:

好的,这是 posts.html 文件:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link href='https://fonts.googleapis.com/css?family=Indie+Flower' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Pacifico' rel='stylesheet' type='text/css'>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet" type='text/css'">
<script src="https://code.jquery.com/jquery-2.1.4.min.js">
</script>
    <style>
      .title {
        font-family: 'Indie Flower', serif;
        font-size: 30px;
        color: #1E90FF;
      }
      h1 {
        font-family: 'Pacifico', serif;
        font-size: 45px;
        color: #1E90FF;
      }
    </style>
</head>
<body>
<div class="container"><h1>My blog</h1><br>
{% for post in allposts %}
    <div>
        <div class="title">{{ post.title }}</div>
        <strong>Published on {{ post.whenPublished }} by {{ post.author }}.</strong>
        <p>{{ post.text|linebreaks }}</p>
    </div>
{% endfor %}
</div>
</body>
</html>

在上面的模板中,换行过滤器用于将纯文本中的换行符替换为相应的 HTML 等效项(

) 通过段落分隔正确格式化每个帖子。

接下来,我们需要在应用程序中的 URL 和返回数据的相应视图之间建立映射。为此,请在 myblog 内创建一个名为 urls.py 的文件,其中包含以下内容:


from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'^$', views.posts, name='posts'),
]

r'^$' 值得更多解释。前导的 r 指示 Django 将单引号内的字符串视为正则表达式。

特别是,r'^$' 表示一个空字符串,因此当我们将浏览器指向 http://ip-address:8000(没有其他内容)时, views.py 中的变量 posts 返回的数据(参考上一节)将显示在我们的主页中:

最后但并非最不重要的一点是,我们将博客应用程序的 urls.py 文件 (~/myfirstdjangoenv/myfirstdjangoproject/myblog/urls.py) 包含到 我们主项目的 urls.py (~/myfirstdjangoenv/myfirstdjangoproject/myfirstdjangoproject/urls.py):


from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'', include('myblog.urls')),
]

然后让我们启动网络服务器:


cd ~/myfirstdjangoenv/myfirstdjangoproject
python manage.py runserver 0.0.0.0:8000

我们现在应该能够看到我们之前创建的帖子列表:

感谢 Bootstrap,您仍然可以在较小的设备中获得出色的可视化效果:

加起来

现在让我们回顾一下本文和本系列中涵盖的概念:

1. 每个模型定义一个对象并映射到一个数据库表,数据库表的字段又映射到该对象的属性。另一方面,模板定义了将显示视图返回的数据的用户界面。

假设我们想要通过向 Post 对象添加一个名为 summary 的字段来修改我们的模型,我们将在其中存储每个帖子的可选简短描述。让我们在 myblog/models.py 中添加以下行:

summary = models.CharField(max_length=350, blank=True, null=True)

正如我们在上一篇文章中了解到的,我们需要将更改迁移到数据库:


python manage.py makemigrations myblog
python manage.py migrate myblog

然后使用管理界面编辑帖子并为每个帖子添加简短摘要。最后,替换模板中的以下行 (posts.html):

<p>{{ post.text|linebreaks }}</p>

<p>{{ post.summary }}</p>

刷新主页即可看到变化:

2. view 函数接受 HTTP 请求并返回 HTTP 响应。在本文中,views.py 中的 def posts(request) 调用底层数据库来检索所有帖子。如果我们想检索标题中包含 ansible 一词的所有帖子,我们应该替换。

posts = Post.objects.filter(whenPublished__lte=timezone.now()).order_by('-whenPublished')

posts = Post.objects.filter(title__icontains="ansible").order_by('-whenPublished')

通过将 Web 应用程序中的用户界面与应用程序逻辑分离,Django 简化了维护和升级应用程序的任务。

3. 如果您遵循本系列中提供的说明,您的项目结构应如下所示:


myfirstdjangoenv/myfirstdjangoproject
├── db.sqlite3
├── manage.py
├── myblog
│   ├── admin.py
│   ├── admin.pyc
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── 0001_initial.pyc
│   │   ├── __init__.py
│   │   └── __init__.pyc
│   ├── models.py
│   ├── models.pyc
│   ├── templates
│   │   └── myblog
│   │       └── posts.html
│   ├── tests.py
│   ├── urls.py
│   ├── urls.pyc
│   ├── views.py
│   └── views.pyc
└── myfirstdjangoproject
    ├── __init__.py
    ├── __init__.pyc
    ├── settings.py
    ├── settings.pyc
    ├── urls.py
    ├── urls.pyc
    ├── wsgi.py
    └── wsgi.pyc

如果上面的列表在您的浏览器中无法正确显示,请参阅以下命令的输出屏幕截图:


tree myfirstdjangoenv/myfirstdjangoproject

概括

尽管所有这些概念乍一看可能有点令人生畏,但我可以向您保证 Django 非常值得您付出一切必要的努力来熟悉它

我希望我们在本系列中使用的向您介绍这个出色的 Web 框架的示例能够激励您了解更多信息。如果是这样,官方 Django 文档(不断更新)是最好的起点。

我可以向您保证,Django 的功能远远超出了我们在一系列文章中所能充分介绍的范围,因此请随意探索它并边做边学!

请随时使用下面的表格向我们提出问题或建议。