如何使用 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 的功能远远超出了我们在一系列文章中所能充分介绍的范围,因此请随意探索它并边做边学!
请随时使用下面的表格向我们提出问题或建议。