Tutorials

在 PyCharm 中创建 Django 应用

Read this post in other languages:

Django 的核心思想是让开发者快速构建应用程序。 掌握这个框架后,从概念到可以投入生产的 Web 应用程序的路径将大幅缩短。 但是,如果您还想更快,可以学习在 PyCharm 中创建 Django 应用。

本教程将通过一系列步骤指导您创建一个简单的 Django 应用程序,显示所在位置的当前气温。 为了增加互动性,这款应用还可供浏览其他随机位置的天气状况。

在本教程中,您将学习如何:

  • 在 PyCharm 中创建 Django 项目。
  • 编写模型、视图和模板。
  • 进行 API 调用并处理响应。
  • 连接到数据库并使用数据填充。

克隆仓库即可获取完整的应用程序代码。 要了解有关克隆的信息,请参阅 PyCharm 文档

前提

本教程适合已经有数年 Python 经验的开发者。 因此,我们假设您的电脑上已经安装了 Python。 如果不是这样,也别担心! 开始在 PyCharm 中创建第一个项目时,您可以下载并安装需要的 Python 版本。

对 Django 的支持是一项专业功能,因此您需要 PyCharm Professional。 新用户有 30 天的免费试用期,如果您是学生或教师,可以申请免费教育许可证。 本教程基于已启用新 UIPyCharm 2023.1

有关不同操作系统的更多信息和安装说明,请参阅 PyCharm 文档

开始构建应用

我们先迈出第一步。 步骤不多,最后,您将得到一个基础应用。

在 PyCharm 中创建 Django 项目

要创建项目,首先启动 PyCharm 并点击 New Project(新建项目)。 如果 PyCharm 已经在运行,可以从主菜单中选择 File | New Project(文件 | 新建项目)。

在打开的 New Project(新建项目)窗口中,指定以下信息:

在 PyCharm 中创建 Django 项目
  1. 选择 Django 作为项目类型。
  2. 输入项目所在目录的名称。 这也将用作项目名称。
  3. 为新 Django 项目创建虚拟环境,PyCharm 将在其中安装依赖项。 在本教程中,我们将选择 virtualenv 选项。
  4. PyCharm 可以立即在项目中创建 Django 应用程序。 务必在这里为应用程序命名。

准备好后,点击 Create(创建)。 PyCharm 创建文件结构,并安装 Django 和其他需要的依赖项。 

点击窗口顶部的 Run(运行)图标启动 Django 服务器:

运行 Django 服务器

这将打开 Run(运行)工具窗口。 点击链接打开浏览器窗口:

浏览器中的 Django 服务器页面

在 PyCharm 中启动 Django 服务器只需要几分钟的时间。 这是一个好的开始,但最好的还在前面。

编写首个视图

现在,开始创建应用程序逻辑。 在 Django 中,在 views.py 中编写类或函数。

您可以随时点击 PyCharm 窗口左上角的文件夹图标,也可以按 ⌘1 / Alt+1 来探索项目的结构:

访问 Project(项目)工具窗口

本教程包含可以节省大量时间的快捷键,例如按两次 ⇧ (Shift) 键可以打开 Search Everywhere(随处搜索)窗口。 这个快捷键可以找到任何内容,包括项目文件、设置和操作。

我们用它来快速打开 views.py

输入 views,将光标移动到 meteo 处的 views.py,然后按 Enter

使用 Search Everywhere(随处搜索)

带有 views.py 的编辑器标签页随即打开。 我们先编写一个 temp_here 函数,它将返回我们位置的当前温度。 

在编辑器中粘贴以下代码:

import requests


def temp_here():
    location = geocoder.ip('me').latlng
    endpoint = "https://api.open-meteo.com/v1/forecast"
    api_request = f"{endpoint}?latitude={location[0]}&longitude={location[1]}&hourly=temperature_2m"
    return requests.get(api_request).json()

这里发生了什么? 首先,导入 API 调用所需的 requests 库。 如果 import 语句中有红色波浪线,则表示软件包在所选 Python 解释器中不可用。

将光标悬停在它上面,选择 Install package requests(安装软件包请求)。

安装请求库

为了获取当前温度,temp_here 会调用 Weather Forecast API。 这是一个不需要 API 密钥的免费 API。 我们只需要知道端点 (https://api.open-meteo.com/v1/forecast) 和坐标。 对于后者,我们将使用 Geocoder – 这是一个非常简单的 Python 库,可供检索不同位置的坐标。

将文本光标放在以红色波浪线高亮显示的 geocoder 上,然后按 ⌥Enter / Alt+Enter 查看可用的快速修复。 选择 Install and import package ‘geocoder’(安装并导入软件包 ‘geocoder’):

安装并导入 Python 软件包

PyCharm 会安装软件包并将 import 语句添加到文件的开头。

那么,如何发出测试请求来确保一切按预期工作? 最简单的方式是在 Python 控制台中调用函数。

我们来使用另一个节省时间的方式 – Find action(查找操作)。 不用在菜单中滑动鼠标,也不用背下几十个快捷键,只需按 ⇧⌘A / Ctrl+Shift+A,然后搜索 Run File in Python Console(在 Python 控制台中运行文件)。

您不需要打出整个单词。 使用 rufipy 这样的词也会得到想要的结果:

运行命令时,PyCharm 会将 import 和函数定义加载到控制台中。 现在,调用 temp_here。 按 Tab 键可以补全代码:

在 Python 控制台中使用代码补全

检查来自控制台输出的 API 响应。 这个字符串很长,但下面有说明性表示。

如果要探索响应,可以遵循以下步骤:

  1. 点击 3 次控制台输出,然后按 ⌘C / Ctrl+C 将其复制到剪贴板。
  2. ⇧⌘N / Ctrl+Alt+Shift+Insert 创建临时文件,然后选择 JSON 文件类型(输入 js… 即可)。
  3. 粘贴响应并应用 Reformat Code(重新格式化代码)操作。 可以使用 Find action(查找操作)或按 ⌥⌘L / Ctrl+Alt+L

所需信息位于 temperature_2m 键下的 hourly 元素中。 此键指向一个值列表。

为了获取当前温度,我们必须将当前小时作为索引。 例如,如果现在是 14:30,我们将使用列表的第 14 项。

探索 API 响应

看一下 temp_here()['hourly']['temperature_2m'][14] 是否提供了需要的信息。

根据当前时间替换 14,并在控制台中输入代码:

从 Python 控制台向 API 发送请求

14.9 °C 是我们所在位置的当前温度。 您那里呢?

修改函数,让它从 API 响应中提取当前温度:

def temp_here():
    location = geocoder.ip('me').latlng
    endpoint = "https://api.open-meteo.com/v1/forecast"
    api_request = f"{endpoint}?latitude={location[0]}&longitude={location[1]}&hourly=temperature_2m"
    now = datetime.now()
    hour = now.hour
    meteo_data = requests.get(api_request).json()
    temp = meteo_data['hourly']['temperature_2m'][hour]
    return temp

记得导入 datetime

点击 Python 控制台工具栏左上角的 Rerun(重新运行),重新加载更新的函数定义,然后再次调用 temp_here

从 Python 控制台调用更新的函数

如果结果与更改 temp_here 函数代码之前的结果不同,那可能是因为 settings.py 中的 TIME_ZONE 值错误。 

有关详情,请参阅 Django 文档

要快速访问此设置,首先按两次 ⇧ (Shift),按几次 Tab 切换到 Symbols(符号),然后输入 time…

使用 Search Everywhere(随处搜索)搜索设置

接下来,将 temp_here 变成视图函数。 要被 Django 识别为视图,函数必须接受 HttpRequest 对象作为其第一个形参,通常命名为 request。 它还应该返回 HttpResponse 对象。

以下是 views.py 的样子:

from datetime import datetime

import geocoder as geocoder
import requests
from django.http import HttpResponse


def temp_here(request):
    location = geocoder.ip('me').latlng
    endpoint = "https://api.open-meteo.com/v1/forecast"
    api_request = f"{endpoint}?latitude={location[0]}&longitude={location[1]}&hourly=temperature_2m"
    now = datetime.now()
    hour = now.hour
    meteo_data = requests.get(api_request).json()
    temp = meteo_data['hourly']['temperature_2m'][hour]
    return HttpResponse(f"Here it's {temp}")

如您所见,我们没有做太多更改:temp_here 现在接受 request 作为实参并返回带有字符串的 HttpResponse

如果您偏好华氏度而不是摄氏度,这很容易实现,只需将 temperature_unit 形参添加到 API 请求:

api_request = f"{endpoint}?latitude={location[0]}&longitude={location[1]}&hourly=temperature_2m&temperature_unit=fahrenheit"

如果您更喜欢使用摄氏度,则跳过此修改。

配置 URL

更新 urls.py,配置从浏览器访问应用的方式。 按两次 Shift,输入 urls,如上所述查找和打开。

将以下行添加到 urlpatterns。 使用 Reformat Code(重新格式化代码)操作 ⌥⌘L / Ctrl+Alt+L 可以在粘贴后轻松还原缩进:

path("", include('meteo.urls')),

不要忘记从 django.urls.include 导入 include

'meteo.urls' 现在被标记为带有黄色波浪线的未解析引用,因为文件尚不存在。 这将在后续步骤中得到修正。

Django 项目通常包含多个应用。 即使目前并非如此,也要考虑项目的未来发展。 因此,我们在对应文件夹中为每个应用程序创建 urls.py ,然后将它们全部添加到项目的 urls.py 中。

接下来,在 meteo 应用程序的文件夹中创建 urls.py

Project(项目)工具窗口中右键点击 meteo 目录。

选择 New > Python File(新建 > Python 文件),输入 urls

新创建的文件将打开。 使用以下代码填充:

from django.urls import path
from . import views


urlpatterns = [
    path('meteo/', views.temp_here, name='temp_here'),
]

现在,当我们在浏览器中转到 <server_address>/meteo 时,views.py 中的 temp_here 函数将被调用,浏览器将渲染函数返回的任何内容。

它上线了!

点击右上角的 Rerun(重新运行)按钮重新运行 Django 服务器并确认操作:

重新运行 Django 服务器

在浏览器中打开 http://127.0.0.1:8000/meteo/。 您看到的内容应该类似于:

浏览器中的应用程序页面

如果您不想在每次重新启动 Django 服务器时打开浏览器输入地址,或手动刷新页面,可以将 PyCharm 配置为代您完成这些操作。

打开 Run(运行)微件中的下拉菜单,选择 Edit configurations(编辑配置):

编辑运行配置

在左窗格中选择项目的配置,启用 Run browser(运行浏览器)复选框,然后将 meteo 添加到 url:

配置 URL

点击 OK(确定)应用更改。

基本上,应用已经可以运行了。 但它在浏览器中不太好看,而且仍然没有“随机位置天气”功能。 在接下来的步骤中,我们将引入模板并导入数据来解决这些问题。

改进体验

添加模板

我们回到 views.py,再次修改 temp_here 函数。 如果您还在 meteo/urls.py 中,可以立即导航到那里。 按住 / Ctrl,将鼠标悬停在 temp_here 上,当它变成超链接时点击:

导航到函数定义

在 return 语句之前开始一个新行并输入“template = loader”。

⌥Enter/ Alt+Enter 并使用快速修复从 django.template.loader 导入 loader

然后,使用 get_template() 加载 index.html 作为模板:

    template = loader.get_template('index.html')

现在,将 return 语句替换为以下两行:

    context = {'temp': temp}
    return HttpResponse(template.render(context, request))

Index.html 以黄色波浪线高亮显示,因为它尚不存在。 将光标悬停在它上面并选择 Create template index.html(创建模板 index.html)。

创建模板文件

点击 OK(确定)。 PyCharm 将创建 index.html 并打开它进行编辑。

文件现在为空。 使用 Live Template(实时模板)填充模板 html 代码。 输入 html:5,按 Tab

使用实时模板

html 页面的可见内容位于 <body></body> 标记之间。 

在这里插入以下代码:

<h1>Temperature at your location:</h1>
<h2>{{ temp }} ℃</h2>

temp 是从视图传递给模板的变量。 变量的名称和值应保存到字典中,并在渲染模板时传递。 为此,我们将 {‘temp’ : temp} 赋给以上 views.py 中的上下文变量。 

摄氏度符号的 Unicode 表示是 &#8451。 华氏度使用 &#8457。 

接下来,重新运行 Django 服务器查看更改,并确保应用按预期工作。 如果您已按上述说明编辑了运行配置,浏览器窗口应自动打开:

从模板生成的应用程序页面

创建数据库和模型

为了从 API 获取随机位置的温度数据,我们需要提供这些位置的坐标。

为此,使用 Juanma HernándezCC BY 4.0 许可下提供的 World cities 数据库。 下载数据库并从归档提取 worldcities.csv。 如果您在 Kaggle 还没有帐户,则必须注册。

我们还需要将 Django 自动创建的 db.sqlite3 数据库添加到我们的 PyCharm 项目。

为此:

  1. 点击右侧的数据库图标打开 Database(数据库)工具窗口。 您也可以按 ⌘E / Ctrl+E 访问所有工具窗口:
访问 Database(数据库)工具窗口
  1. 点击工具窗口左上角的 +,选择 Data Source > SQLite(数据源 > SQLite)。 输入 sq… 可以更快地找到所需选项:
创建 SQL Lite 数据源
  1. 点击 File(文件)字段旁边的 ,在项目文件夹中查找 db.sqlite3 文件。
  2. 您可能需要安装、更新或切换数据库驱动程序。 如果窗口底部出现警告,则点击链接执行所需操作:
安装/切换数据库驱动程序
  1. 点击 OK(确定)。

为了将数据导入数据库,应在 Database(数据库)工具窗口中将 worldcities.csv 拖放到 db.sqlite3。 在打开的对话框中,移除不必要的列,只保留 city、lat、lng、countryid

现在,db.sqlite3 数据库包含 worldcities 表:

数据库结构中的 Worldcities 表

双击即可在编辑器中查看其内容。

Django 使用模型与数据库交互。 创建一个模型来实现从 worldcities 表读取数据。

  1. ⌥R / Ctrl+Alt+R 启动 manage.py 任务控制台。 
  2. 输入 inspectdb worldcities 并按 Enter
  3. Worldcities 类从控制台输出复制到 meteomodels.py
  4. 将 id 字段的 null=True 替换为 primary_key=True

以下是它的样子:

from django.db import models


class Worldcities(models.Model):
    city = models.TextField(blank=True, null=True)
    lat = models.FloatField(blank=True, null=True)
    lng = models.FloatField(blank=True, null=True)
    country = models.TextField(blank=True, null=True)
    id = models.IntegerField(blank=True, primary_key=True)

    class Meta:
        managed = False
        db_table = 'worldcities'

添加功能

目前为止,我们在 views.py 中只有一个函数 (temp_here) 可以返回有关您所在位置当前温度的信息。 我们再添加一个函数来显示随机位置的温度。 它也需要从 API 获取当前温度数据,因此根据 Python 最佳做法,我们应该将该功能移动到单独的函数。

在 PyCharm 中,这可以通过 Extract method(提取方法)重构轻松完成。

选择应移至单独函数的行,然后按 ⌥⌘M / Ctrl+Alt+M。 或者,使用 Find Action(查找操作):

Method name(方法名称)字段中指定 get_temp,然后点击 OK(确定)。 我们现在有了接受 location 作为唯一形参的 get_temp 函数。

temp_here 函数调用它来接收当前位置的温度。

Extract Method(提取方法)重构的结果

我们来创建 temp_somewhere 函数。 它应该将随机城市的坐标传递给 get_temp

首先,在 Python 控制台中进行一些原型设计。 打开并粘贴以下代码(如果出现 ImportError,则关闭并重新打开控制台):

from meteo.models import Worldcities
random_item = Worldcities.objects.all().order_by('?').first()

我们需要从 worldcities 表获取数据。 这是通过模型完成的,因此我们从 models.py 导入 Worldcities 模型。

然后,使用 order_by(‘?’) 随机化所有对象并使用 first() 获得第一个对象。 在 Python console(Python 控制台)工具窗口的右侧,有一个 Variables(变量)标签页。 展开 random_item 节点,查看 random_item 的内容:

在 Python 控制台的 Variables(变量)标签页中检查变量

temp_somewhere 函数的完整代码如下所示:

def temp_somewhere(request):
    random_item = Worldcities.objects.all().order_by('?').first()
    city = random_item.city
    location = [random_item.lat, random_item.lng]
    temp = get_temp(location)
    template = loader.get_template("index.html")
    context = {
        'city': city,
        'temp': temp
    }
    return HttpResponse(template.render(context, request))

除了温度,context 现在还包含城市名称。 我们来编辑模板,使其也呈现此信息。

您可能已经注意到装订区域中的 <> 图标。 点击以快速切换到 index.html

用于快速访问模板文件的装订区域图标

<h1></h1> 标记之间的文本替换为 {{ city }}

将标题替换为变量

点击装订区域图标可快速访问 temp_here 函数:

用于快速访问 Python 文件的装订区域图标

我们需要修改它,使它也传递 city 变量:

更新 temp_here 函数

在浏览器中打开 https://127.0.0.1/meteo 页面时将调用 temp_here 函数,我们已在 meteo/urls.py 中完成配置。

我们回到那里,指定在访问 https://127.0.0.1/meteo/discover 时应调用 temp_somewhere

urlpatterns = [
    path('meteo/', views.temp_here, name='temp_here'),
    path('meteo/discover', views.temp_somewhere, name='temp_somewhere'),
]

返回 index.html,添加指向 /discover 页面和首页的链接。 后者将始终显示当前位置的温度。 实时模板和代码补全可以节省大量时间:

要对 html 文件中的段落和链接使用实时模板,只需分别输入 pa ,然后按 Tab

要查看可用实时模板的完整列表,首先打开设置 ( / Ctrl+Alt+S),转到 Editor > Live Templates(编辑器 > 实时模板),然后展开右窗格中的 Zen HTML 节点:

配置实时模板设置

您可以重新运行服务器并试用应用程序:

还没结束

应用现在可以运行,但还有改进的空间。 最明显的是视觉外观,但也还可以添加额外功能。

使用 CSS

CSS 是使 Django 应用程序看起来更好的最快也最简单的方式。 例如,使用 Simple.CSS

将以下行放在 index.html<head></head> 标记之间的任意位置:

<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">

新外观:

应用 CSS

将链接替换为按钮也将改善外观:

将链接替换为按钮

为此,将 index.html<p></p> 标记之间的链接替换为以下 html 代码:

<div style="display: flex;">
    <form action="./discover">
        <input type="submit" value="Check other places"/>
    </form>
    &nbsp;
    <form action=".">
        <input style="background: #dc3545" type="submit" value="Home"/>
    </form>
</div>

无需从 PyCharm 切换到浏览器即可看到编辑 index.html 的结果。 将鼠标悬停在编辑器窗口的右上角,选择 Built-in Preview(内置预览):

使用 Bootstrap

Bootstrap 是一个强大且免费的前端工具包。 要将它快速应用到 Django 应用,按如下所示编辑 index.html(有关详情,请参阅 Bootstrap 快速入门指南):

  1. link 标记添加到 html 头部(替换前面步骤中的 simple.css):
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">

2. 在 <body></body> 标记内添加以下代码:

<div class="container text-center">
    <h1>{{ city }}</h1>
    <h2>{{ temp }} ℃</h2>
    <div class="btn-group" role="group">
        <button type="button" class="btn btn-outline-primary" onclick="location.href='./discover'">Check other places
        </button>
        <button type="button" class="btn btn-danger" onclick="location.href='.'">Home</button>
    </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>

查看结果:

在应用程序中使用 Bootstrap

Bootstrap 提供了多种自定义应用外观的方式。 您可以在文档中找到所有必要信息。

亲自尝试

我们已将 worldcities 数据库的 country 字段添加到 Worldcities 模型中,但并未在应用的任何地方使用该数据。 现在,您还可以测试自己的技能,让应用除了城市名称之外还显示国家/地区。 结果应该类似于:

将国家/地区信息添加到应用程序

总结

在本教程中,我们学习了如何:

  • 在 PyCharm 中创建 Django 项目。
  • 编写视图和创建模板。
  • 进行 API 调用并处理响应。
  • 连接数据库和导入数据。
  • 应用 CSS 和 Bootstrap 改善应用的视觉外观。

本博文英文原作者:

image description

Discover more