Katie Mclaughlin 发布的文章

开源意味着我可以在任何终端上找到熟悉的 Linux。

十年前,我开始了我的第一份工作,它要求我使用 Linux 作为我的笔记本电脑的操作系统。如果我愿意的话,我可以使用各种 Linux 发行版,包括 Gentoo,但由于我过去曾短暂地使用过Ubuntu,所以我选择了 Ubuntu Lucid Lynx 10.04。

我的 Konsole 终端使用的是 Zenburn 主题,有一个类似于这样的 Bash 提示符:

machinename ~/path/to/folder $

现在,我使用 Mac,具体来说是 macOS Catalina,我使用 iTerm2Zenburn 主题,zsh 提示符是这样的:

machinename ~/path/to/folder
$

我想,十年来几乎相同的提示符,我已经赢得了老古板的称号,不过这只是标志着,我的喜好和习惯与现在耍酷的孩子们不一样而已。

仿佛是为了证明我的古板观点,我想改变我的终端和我的旧终端一样。在 Mac 上获得一个看起来和感觉像 Lucid Lynx 的设置并不简单,而且我很花了一些时间。

我最近最大的改变是从 Bash 转移到 zsh,并迁移了我的 Bash 魔改。但这只是其中一个重大的转变。我学到了许多新式的经验,现在我把这些经验赠送给你,亲爱的读者。

Coreutils 对选项的顺序更宽容

从 Ubuntu 转移到 macOS 并没有太大的转变,直到我开始觉得我失去了 Unix 范。我试着运行一些基本的操作,比如删除文件夹,但却被告知我错误地调用了 rm

事实证明,GNU 风格的实用程序可能看起来 BSD 风格的差不多,但最大的可用性差异之一是参数顺序。未命名参数的排列顺序并不一致。例如:rm

下面是我们熟悉的 GNU 风格的删除目录的命令:

$ rm path/to/folder -rf

这与同一命令的 BSD 风格版本形成鲜明对比:

$ rm path/to/folder -rf
rm: path/to/folder: is a directory
rm: -rf: No such file or directory

我通过 Homebrew 安装 Coreutils 解决了这个问题。这将 GNU 实用程序引入到了 macOS,并使我不必为那些已经深深扎根于我的肌肉记忆中的命令记住选项顺序,从而对选项顺序更加宽容。

强大的 iTerm2

我不知道有哪个操作系统的资深用户会对默认终端满意。在 macOS 这块土地上,我选择了 iTerm2,它允许我比基本的操作系统终端应用更灵活。我最喜欢的 iTerm 强大功能之一是能够使用 Command+DCommand+Shift+D 来垂直和水平分割窗格。还有很多技巧需要学习,但仅是简单的分割窗格就值得用 iTerm2 换掉默认终端。

上下文感知的插件

即使是一个古板的用户也会自定义终端提示,其中一个原因是为了获得一些情境感知。我喜欢终端给我提供上下文,并回答所有想到的问题。不仅仅是我在哪个文件夹里,而是:我在什么机器上?这是个 Git 仓库吗?如果是,我在哪个分支?我是在 Python 虚拟环境中吗?

这些问题的答案最终都归结为一类称之为“上下文感知插件”的终端扩展。

对于当前的 Git 分支,我使用了这个 parse\_git\_branch() 方法(如果你使用的是 Oh My Zsh,也有类似的插件)。对于 Python 来说,virtualenv 会自动给提示符加前缀。Oh My Zsh 有如此多的插件,你一定能找到改善你生活的东西。

至于我的本地机?我就直接用 PS1 格式,因为我喜欢这样的基本信息,而且 macOS 并没有真正让你给机器起个名字。

多行提示符也不错

观察力强的读者可能会注意到,十年来我的提示符有一个变化,就是现在它是两行。这是最近的一个变化,我慢慢学会了喜欢,因为我前面提到的所有这些插件都让我的提示符变得很长很长。你在文件系统中导航不能太深,要不你试图做任何基本的事情都会输入换行。随之而来的是偶尔的重绘问题和可读性问题。

我收到的关于解决这个问题的建议大多围绕着“哦,你在用 zsh?用 Powerlevel10k 吧!”这对于像我这样不固步自封的人来说是不错的,但我能够从这些主题中学习到一些,并从中获取一点技巧。

我所做的是在我的提示符中的最后一个 $ 前加一个 $'\n',这样我的上下文信息 —— 当前机器、当前文件夹、当前 GitHub 分支、当前 virtualenv 等等 —— 都可以在一行中出现,然后我的命令就可以顺利输入了。

我发现唯一的问题是学会在哪里。我习惯于让我的眼睛从行的中心开始,因为以前我的提示符就是从那里开始的。我正在慢慢学会向左看提示符,但这是一个缓慢的过程。我有十几年的眼睛习惯要撤销。

使用适合你的方法

如果你喜欢某种风格或工具,那么你的这种偏好是绝对有效的。你可以尝试其他的东西,但千万不要认为你必须使用最新和最伟大的,只是为了像很酷的孩子一样。你的风格和喜好可以随着时间的推移而改变,但千万不要被迫做出对你来说不舒服的改变。

等下一次,凯蒂阿姨再给你吐槽一下 IDE。


via: https://opensource.com/article/20/7/mac-terminal

作者:Katie McLaughlin 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

通过别名和其他捷径来提高你经常忘记的那些事情的效率。

要是你整天使用计算机,如果能找到需要重复执行的命令并记下它们以便以后轻松使用那就太棒了。它们全都呆在那里,藏在 ~/.bashrc 中(或 zsh 用户~/.zshrc 中),等待着改善你的生活!

在本文中,我分享了我最喜欢的这些助手命令,对于我经常遗忘的事情,它们很有用,也希望这可以帮助到你,以及为你解决一些经常头疼的问题。

完事吱一声

当我执行一个需要长时间运行的命令时,我经常采用多任务的方式,然后就必须回头去检查该操作是否已完成。然而通过有用的 say 命令,现在就不用再这样了(这是在 MacOS 上;请根据你的本地环境更改为等效的方式):

function looooooooong {
    START=$(date +%s.%N)
    $*
    EXIT_CODE=$?
    END=$(date +%s.%N)
    DIFF=$(echo "$END - $START" | bc)
    RES=$(python -c "diff = $DIFF; min = int(diff / 60); print('%s min' % min)")
    result="$1 completed in $RES, exit code $EXIT_CODE."
    echo -e "\n⏰  $result"
    ( say -r 250 $result 2>&1 > /dev/null & )
}

这个命令会记录命令的开始和结束时间,计算所需的分钟数,并“说”出调用的命令、花费的时间和退出码。当简单的控制台铃声无法使用时,我发现这个超级有用。

安装小助手

我在小时候就开始使用 Ubuntu,而我需要学习的第一件事就是如何安装软件包。我曾经首先添加的别名之一是它的助手(根据当天的流行梗命名的):

alias canhas="sudo apt-get install -y"

GPG 签名

有时候,我必须在没有 GPG 扩展程序或应用程序的情况下给电子邮件签署 GPG 签名,我会跳到命令行并使用以下令人讨厌的别名:

alias gibson="gpg --encrypt --sign --armor"
alias ungibson="gpg --decrypt"

Docker

Docker 的子命令很多,但是 Docker compose 的更多。我曾经使用这些别名来将 --rm 标志丢到脑后,但是现在不再使用这些有用的别名了:

alias dc="docker-compose"
alias dcr="docker-compose run --rm"
alias dcb="docker-compose run --rm --build"

Google Cloud 的 gcurl 助手

对于我来说,Google Cloud 是一个相对较新的东西,而它有极多的文档gcurl 是一个别名,可确保在用带有身份验证标头的本地 curl 命令连接 Google Cloud API 时,可以获得所有正确的标头。

Git 和 ~/.gitignore

我工作中用 Git 很多,因此我有一个专门的部分来介绍 Git 助手。

我最有用的助手之一是我用来克隆 GitHub 存储库的。你不必运行:

git clone [email protected]:org/repo /Users/glasnt/git/org/repo

我设置了一个克隆函数:

clone(){
    echo Cloning $1 to ~/git/$1
    cd ~/git
    git clone [email protected]:$1 $1
    cd $1
}

即使每次进入 ~/.bashrc 文件看到这个时,我总是会忘记和傻笑,我也有一个“刷新上游”命令:

alias yoink="git checkout master && git fetch upstream master && git merge upstream/master"

给 Git 一族的另一个助手是全局忽略文件。在你的 git config --global --list 中,你应该看到一个 core.excludesfile。如果没有,请创建一个,然后将你总是放到各个 .gitignore 文件中的内容填满它。作为 MacOS 上的 Python 开发人员,对我来说,这些内容是:

.DS_Store     # macOS clutter
venv/         # I never want to commit my virtualenv
*.egg-info/*  # ... nor any locally compiled packages
__pycache__   # ... or source
*.swp         # ... nor any files open in vim

你可以在 Gitignore.io 或 GitHub 上的 Gitignore 存储库上找到其他建议。

轮到你了

你最喜欢的助手命令是什么?请在评论中分享。


via: https://opensource.com/article/20/1/bash-scripts-aliases

作者:Katie McLaughlin 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Python 2 将在几周内走到生命终点,这篇文章是你迁移到 Python 3 之前应该知道的。

从 2020 年 1 月 1 日开始,Python 2.7 将不再得到正式支持。在此日期之后,将会发布一个最终错误修复计划,但是仅此而已。

Python 2 的生命终点(EOL)对你意味着什么?如果正在运行着 Python 2,你需要迁移。

是谁决定 Python 2 的生命终点?

2012 年,维护 Python 编程语言的团队审查了其选项。有两个越来越不同的代码库,Python 2 和 Python 3。这两者都很流行,但是较新的版本并未得到广泛采用。

除了 Python 3 中完全重写的 Unicode 支持改变了处理数据的底层方式造成的断层,这个主要版本的变化还一次性出现了一些非向后兼容的更改。这种断层的决定成文于 2006 年。为了减轻该断层的影响,Python 2 继续保持了维护,并向后移植了一些 Python 3 的功能。为了进一步帮助社区过渡,EOL 日期从 2015 年延长至 2020 年,又延长了五年。

该团队知道,维护不同的代码库是必须解决的麻烦。最终,他们宣布了一项决定:

“我们是制作和照料 Python 编程语言的志愿者。我们已决定 2020 年 1 月 1 日将是我们停止使用 Python 2 的日子。这意味着在这一天之后,即使有人发现其中存在安全问题,我们也将不再对其进行改进。你应尽快升级到 Python 3。”

Nick Coghlan 是 CPython 的核心开发人员,也是 Python 指导委员会的现任成员,在他的博客中添加了更多信息。由 Barry Warsaw(也是 Python 指导委员会的成员)撰写的 PEP 404 详细说明了 Python 2.8 永远不会面世的原因。

有人还在支持 Python 2 吗?

提供者和供应商对 Python 2 的支持会有所不同。Google Cloud 宣布了它计划未来如何支持 Python 2。红帽还宣布了红帽企业 Linux(RHEL)的计划,而 AWS 宣布了 AWS 命令行界面和 SDK次要版本更新要求

你还可以阅读 Vicki Boykis 在 Stack Overflow 撰写的博客文章“为什么迁移到 Python 3 需要这么长时间?”,其中她指出了采用 Python 3 缓慢的三个原因。

使用 Python 3 的原因

不管是否有持续的支持,尽快迁移到 Python 3 是一个好主意。Python 3 将继续受到支持,它具有 Python 2 所没有的一些非常优雅的东西。

最近发布的 Python 3.8 包含 海象运算符位置参数自描述的格式化字符串功能。Python 3 的早期版本引入的功能,例如 异步 IO格式化字符串类型提示pathlib,这里只提及了一点点。

下载最多的前 360 个软件包已迁移到 Python 3。你可以使用 caniusepython3 软件包检查你的 requirements.txt 文件,以查看你依赖的任何软件包是否尚未迁移。

将 Python 2 移植到 Python 3 的参考资源

有许多参考资源可简化你向 Python 3 的迁移。例如,“将 Python 2 移植到 Python 3 指南”列出了许多工具和技巧,可帮助你实现与 Python 2/3 单一源代码的兼容性。在 Python3statement.org 上也有一些有用的技巧。

Dustin IngramChris WilcoxCloud Next ‘19上作了一个演讲,详细介绍了向 Python 3 过渡的一些动机和迁移模式。Trey HunnerPyCon 2018 演讲上介绍了 Python 3 最有用的功能,鼓励你进行迁移,以便你可以利用它们。

加入我们!

距 2020 年 1 月 1 日仅有几周了。如果你需要每天提醒一下它即将到来的时间(并且你使用 Twitter 的话),请关注 Python 2 日落倒计时 Twitter 机器人。


via: https://opensource.com/article/19/11/end-of-life-python-2

作者:Katie McLaughlin 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

通过这篇教程提升你的 top 命令的知识。

尝试找出你的机器正在运行什么程序,以及哪个进程耗尽了内存导致系统非常非常慢 —— 这是 top 命令所能胜任的工作。

top 是一个非常有用的程序,其作用类似于 Windows 任务管理器或 MacOS 的活动监视器。在 *nix 机器上运行 top 将实时显示系统上运行的进程的情况。

$ top

取决于你运行的 top 版本,你会看到类似如下内容:

top - 08:31:32 up 1 day,  4:09,  0 users,  load average: 0.20, 0.12, 0.10
Tasks:   3 total,   1 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.5 us,  0.3 sy,  0.0 ni, 99.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   4042284 total,  2523744 used,  1518540 free,   263776 buffers
KiB Swap:  1048572 total,        0 used,  1048572 free.  1804264 cached Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    1 root      20   0   21964   3632   3124 S   0.0  0.1   0:00.23 bash
  193 root      20   0  123520  29636   8640 S   0.0  0.7   0:00.58 flask
  195 root      20   0   23608   2724   2400 R   0.0  0.1   0:00.21 top

你所用的 top 版本可能跟这个看起来不一样,特别是在显示的列上。

如何阅读输出的内容

你可以根据输出判断你正在运行的内容,但尝试去解释结果你可能会有些困惑。

前几行包含一堆统计信息(详细信息),后跟一个包含结果列的表(列)。让我们从后者开始吧。

这些是系统正在运行的进程。默认按 CPU 使用率降序排序。这意味着在列表顶部的程序正使用更多的 CPU 资源并对你的系统造成更重的负担。对于资源使用而言,这些程序是字面上的消耗资源最多的(top)进程。不得不说,top 这个名字起得很妙。

最右边的 COMMAND 一列报告进程名(启动它们的命令)。在这个例子里,进程名是 bash(一个我们正在运行 top 的命令解释器)、flask(一个 Python 写的 web 框架)和 top 自身。

其它列提供了关于进程的有用信息:

  • PID:进程 ID,一个用来定位进程的唯一标识符
  • USER:运行进程的用户
  • PR:任务的优先级
  • NI:Nice 值,优先级的一个更好的表现形式
  • VIRT:虚拟内存的大小,单位是 KiB(kibibytes)
  • RES:常驻内存大小,单位是 KiB(物理内存和虚拟内存的一部分)
  • SHR:共享内存大小,单位是 KiB(共享内存和虚拟内存的一部分)
  • S:进程状态,一般 I 代表空闲,R 代表运行,S 代表休眠,Z 代表僵尸进程,Tt 代表停止(还有其它更少见的选项)
  • %CPU:自从上次屏幕更新后的 CPU 使用率
  • %MEM:自从上次屏幕更新后的 RES 常驻内存使用率
  • TIME+:自从程序启动后总的 CPU 使用时间
  • COMMAND:启动命令,如之前描述那样

确切知道 VIRTRESSHR 值代表什么在日常操作中并不重要。重要的是要知道 VIRT 值最高的进程就是内存使用最多的进程。当你在用 top 排查为什么你的电脑运行无比卡的时候,那个 VIRT 数值最大的进程就是元凶。如果你想要知道共享内存和物理内存的确切意思,请查阅 top 手册的 Linux Memory Types 段落。

是的,我说的是 kibibytes 而不是 kilobytes。通常称为 kilobyte 的 1024 值实际上是 kibibyte。希腊语的 kilo(χίλιοι)意思是一千(例如一千米是 1000 米,一千克是 1000 克)。Kibi 是 kilo 和 binary 的合成词,意思是 1024 字节(或者 2 10 )。但是,因为这个词很难说,所以很多人在说 1024 字节的时候会说 kilobyte。top 试图在这里使用恰当的术语,所以按它说的理解就好。

屏幕更新说明

实时屏幕更新是 Linux 程序可以做的 非常酷 的事之一。这意味着程序能实时更新它们显示的内容,所以看起来是动态的,即使它们用的是文本。非常酷!在我们的例子中,更新时间间隔很重要,因为一些统计数据(%CPU%MEM)是基于上次屏幕更新的数值的。

因为我们运行在一个持久性的程序中,我们就可以输入一些命令来实时修改配置(而不是停止应用,然后用一个不同的命令行选项再次运行)。

按下 h 调用帮助界面,该界面也显示了默认延迟(屏幕更新的时间间隔)。这个值默认(大约)是 3 秒,但你可以输入 d(大概是 delay 的意思)或者 s(可能是 screen 或 seconds 的意思)来修改它。

细节

在进程列表上面有一大堆有用的信息。有些细节看起来有点儿奇怪,让人困惑。但是一旦你花点儿时间来逐个过一遍,你会发现,在紧要关头,这些是非常有用的。

第一行包含系统的大致信息:

  • top:我们正在运行 top!你好!top
  • XX:YY:XX:当前时间,每次屏幕更新的时候更新
  • up(接下去是 X day, YY:ZZ):系统的 uptime,或者自从系统启动后已经过去了多长时间
  • load average(后跟三个数字):分别是过去一分钟、五分钟、15 分钟的系统负载)

第二行(Task)显示了正在运行的任务的信息,不用解释。它显示了进程总数和正在运行的、休眠中的、停止的进程数和僵尸进程数。这实际上是上述 S(状态)列的总和。

第三行(%Cpu(s))显示了按类型划分的 CPU 使用情况。数据是屏幕刷新之间的值。这些值是:

  • us:用户进程
  • sy:系统进程
  • ninice#Etymology) 用户进程
  • id:CPU 的空闲时间,这个值比较高时说明系统比较空闲
  • wa:等待时间,或者消耗在等待 I/O 完成的时间
  • hi:消耗在硬件中断的时间
  • si:消耗在软件中断的时间
  • st:“虚拟机管理程序从该虚拟机窃取的时间”

你可以通过点击 t(toggle)来展开或折叠 Task%Cpu(s) 行。

第四行(Kib Mem)和第五行(KiB Swap)提供了内存和交换空间的信息。这些数值是:

  • 总内存容量
  • 已用内存
  • 空闲内存
  • 内存的缓冲值
  • 交换空间的缓存值

默认它们是用 KiB 为单位展示的,但是按下 E(扩展内存缩放 extend memory scaling)可以轮换不同的单位:KiB、MiB、GiB、TiB、PiB、EiB(kilobytes、megabytes、gigabytes、terabytes、petabytes 和 exabytes)

top 用户手册有更多选项和配置项信息。你可以运行 man top 来查看你系统上的文档。还有很多 HTML 版的 man 手册,但是请留意,这些手册可能是针对不同 top 版本的。

两个 top 的替代品

你不必总是用 top 查看系统状态。你可以根据你的情况用其它工具来协助排查问题,尤其是当你想要更图形化或更专业的界面的时候。

htop

htop 很像 top,但是它带来了一些非常有用的东西:它可以以图形界面展示 CPU 和内存使用情况。

这是我们在刚才运行 top 的同一环境中 htop 的样子。显示更简洁,但功能却很丰富。

任务统计、负载、uptime 和进程列表仍然在,但是它有了漂亮、彩色、动态的每核 CPU 使用情况,还有图形化的内存使用情况。

以下是不同颜色的含义(你也可以通过按下 h 来获得这些信息的帮助)。

CPU 任务优先级或类型:

  • 蓝色:低优先级
  • 绿色:正常优先级
  • 红色:内核任务
  • 蓝色:虚拟任务
  • 条状图末尾的值是已用 CPU 的百分比

内存:

  • 绿色:已经使用的内存
  • 蓝色:缓冲的内存
  • 黄色:缓存内存
  • 条状图末尾的值显示已用内存和总内存

如果颜色对你没用,你可以运行 htop -C 来禁用它们;那样 htop 将使用不同的符号来展示 CPU 和内存类型。

它的底部有一组激活的快捷键提示,可以用来操作过滤结果或改变排序顺序。试着按一些快捷键看看它们能做什么。不过尝试 F9 时要小心,它会调出一个信号列表,这些信号会杀死(即停止)一个过程。我建议在生产环境之外探索这些选项。

htop 的作者 Hisham Muhammad(是的,htop 的名字就是源自 Hisham 的)在二月份的 FOSDEM 2018 做了一个简短的演讲。他阐述了 htop 不仅有简洁的图形界面,还有更现代的进程信息统计展示方式,这都是之前的工具(如 top)所不具备的。

你可以在手册页面htop 网站阅读更多关于 htop 的信息。(提示:网站背景是一个动态的 htop。)

docker stats

如果你在用 Docker,你可以运行 docker stats 来为容器状态生成一个有丰富上下文的界面。

这可能比 top 更有帮助,因为它不是按进程分类,而是按容器分类的。这点特别有用,当某个容器运行缓慢时,查看哪个容器耗资源最多比运行 top 再找到容器的进程要快。

借助于上面对 tophtop 术语的解释,你应该会更容易理解 docker stats 中的那些。然而,docker stats 文档对每一列都提供了详尽的描述。


via: https://opensource.com/article/18/8/top-tips-speed-up-computer

作者:Katie McLaughlin 选题:lujun9972 译者:ypingcn 校对:pityonline

本文由 LCTT 原创编译,Linux中国 荣誉推出

学习怎么去使用 Python 的 web 框架中的对象关系映射与你的数据库交互,就像你使用 SQL 一样。

 title=

你可能听说过 Django,它是一个被称为“完美主义者的最后期限” 的 Python web 框架。它是一匹 可爱的小矮马

Django 的一个强大的功能是它的 对象关系映射 Object-Relational Mapper (ORM),它允许你就像使用 SQL 一样去和你的数据库交互。事实上,Django 的 ORM 就是创建 SQL 去查询和操作数据库的一个 Python 式方式,并且获得 Python 风格的结果。 我说的一种方式,但实际上,它是一种非常聪明的工程方法,它利用了 Python 中一些很复杂的部分,而使得开发者更加轻松。

在我们开始去了解 ORM 是怎么工作之前,我们需要一个可以操作的数据库。和任何一个关系型数据库一样,我们需要去定义一堆表和它们的关系(即,它们相互之间联系起来的方式)。让我们使用我们熟悉的东西。比如说,我们需要去建模一个有博客文章和作者的博客。每个作者有一个名字。一位作者可以有很多的博客文章。一篇博客文章可以有很多的作者、标题、内容和发布日期。

在 Django 村里,这个文章和作者的概念可以被称为博客应用。在这个语境中,一个应用是一个自包含一系列描述我们的博客行为和功能的模型和视图的集合。用正确的方式打包,以便于其它的 Django 项目可以使用我们的博客应用。在我们的项目中,博客正是其中的一个应用。比如,我们也可以有一个论坛应用。但是,我们仍然坚持我们的博客应用的原有范围。

这是为这个教程事先准备的 models.py

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    published_date = models.DateTimeField(blank=True, null=True)
    author = models.ManyToManyField(Author, related_name="posts")

    def __str__(self):
        return self.title

现在,看上去似乎有点令人恐惧,因此,我们把它分解来看。我们有两个模型:作者(Author)和文章(Post)。它们都有名字(name)或者标题(title)。文章有个放内容的大的文本字段,以及用于发布时间和日期的 DateTimeField。文章也有一个 ManyToManyField,它同时链接到文章和作者。

大多数的教程都是从头开始的,但是,在实践中并不会发生这种情况。实际上,你会得到一堆已存在的代码,就像上面的 model.py 一样,而你必须去搞清楚它们是做什么的。

因此,现在你的任务是去进入到应用程序中去了解它。做到这一点有几种方法,你可以登入到 Django admin,这是一个 Web 后端,它会列出全部的应用和操作它们的方法。我们先退出它,现在我们感兴趣的东西是 ORM。

我们可以在 Django 项目的主目录中运行 python manage.py shell 去访问 ORM。

/srv/web/django/ $ python manage.py shell

Python 3.6.3 (default, Nov  9 2017, 15:58:30)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>

这将带我们进入到交互式控制台。shell 命令 为我们做了很多设置,包括导入我们的设置和配置 Django 环境。虽然我们启动了 shell,但是,在我们导入它之前,我们并不能访问我们的博客模型。

>>> from blog.models import *

它导入了全部的博客模型,因此,我们可以玩我们的博客了。

首先,我们列出所有的作者:

>>> Author.objects.all()

我们将从这个命令取得结果,它是一个 QuerySet,它列出了我们所有的作者对象。它不会充满我们的整个控制台,因为,如果有很多查询结果,Django 将自动截断输出结果。

>>> Author.objects.all()
<QuerySet [<Author: VM (Vicky) Brasseur>, <Author: Rikki Endsley>,
 <Author: Jen Wike Huger>, '...(remaining elements truncated)...']

我们可以使用 get 代替 all 去检索单个作者。但是,我们需要一些更多的信息才能 get 一个单个记录。在关系型数据库中,表有一个主键,它唯一标识了表中的每个记录,但是,作者名并不唯一。许多人都 重名,因此,它不是唯一约束的好选择。解决这个问题的一个方法是使用一个序列(1、2、3 ……)或者一个通用唯一标识符(UUID)作为主键。但是,因为它对人类并不好用,我们可以通过使用 name 来操作我们的作者对象。

>>> Author.objects.get(name="VM (Vicky) Brasseur")
<Author: VM (Vicky) Brasseur>

到现在为止,我们已经有了一个我们可以交互的对象,而不是一个 QuerySet 列表。我们现在可以与这个 Python 对象进行交互了,使用任意一个表列做为属性去查看对象。

>>> vmb = Author.objects.get(name="VM (Vicky) Brasseur")
>>> vmb.name
u'VM (Vicky) Brasseur'

然后,很酷的事件发生了。通常在关系型数据库中,如果我们希望去展示其它表的信息,我们需要去写一个 LEFT JOIN,或者其它的表耦合函数,并确保它们之间有匹配的外键。而 Django 可以为我们做到这些。

在我们的模型中,由于作者写了很多的文章,因此,我们的作者对象可以检索他自己的文章。

>>> vmb.posts.all()
QuerySet[<Post: "7 tips for nailing your job interview">,
 <Post: "5 tips for getting the biggest bang for your cover letter buck">,
 <Post: "Quit making these 10 common resume mistakes">,
 '...(remaining elements truncated)...']

我们可以使用正常的 Python 式的列表操作方式来操作 QuerySets

>>> for post in vmb.posts.all():
...   print(post.title)
...
7 tips for nailing your job interview
5 tips for getting the biggest bang for your cover letter buck
Quit making these 10 common resume mistakes

要实现更复杂的查询,我们可以使用过滤得到我们想要的内容。这有点复杂。在 SQL 中,你可以有一些选项,比如,likecontains 和其它的过滤对象。在 ORM 中这些事情也可以做到。但是,是通过 特别的 方式实现的:是通过使用一个隐式(而不是显式)定义的函数实现的。

如果在我的 Python 脚本中调用了一个函数 do_thing(),我会期望在某个地方有一个匹配的 def do_thing。这是一个显式的函数定义。然而,在 ORM 中,你可以调用一个 不显式定义的 函数。之前,我们使用 name 去匹配一个名字。但是,如果我们想做一个子串搜索,我们可以使用 name__contains

>>> Author.objects.filter(name__contains="Vic")
QuerySet[<Author: VM (Vicky) Brasseur>, <Author: Victor Hugo">]

现在,关于双下划线(__)我有一个小小的提示。这些是 Python 特有的。在 Python 的世界里,你可以看到如 __main__ 或者 __repr__。这些有时被称为 dunder methods,是 “ 双下划线 double underscore ” 的缩写。仅有几个非字母数字的字符可以被用于 Python 中的对象名字;下划线是其中的一个。这些在 ORM 中被用于显式分隔 过滤关键字 filter key name 的各个部分。在底层,字符串用这些下划线分割开,然后这些标记分开处理。name__contains 被替换成 attribute: name, filter: contains。在其它编程语言中,你可以使用箭头代替,比如,在 PHP 中是 name->contains。不要被双下划线吓着你,正好相反,它们是 Python 的好帮手(并且如果你斜着看,你就会发现它看起来像一条小蛇,想去帮你写代码的小蟒蛇)。

ORM 是非常强大并且是 Python 特有的。不过,还记得我在上面提到过的 Django 的管理网站吗?

 title=

Django 的其中一个非常精彩的用户可访问特性是它的管理界面,如果你定义你的模型,你将看到一个非常好用的基于 web 的编辑门户,而且它是免费的。

ORM,有多强大?

 title=

好吧!给你一些代码去创建最初的模型,Django 就变成了一个基于 web 的门户,它是非常强大的,它可以使用我们前面用过的同样的原生函数。默认情况下,这个管理门户只有基本的东西,但这只是在你的模型中添加一些定义去改变外观的问题。例如,在早期的这些 __str__ 方法中,我们使用这些去定义作者对象应该有什么?(在这种情况中,比如,作者的名字),做了一些工作后,你可以创建一个界面,让它看起来像一个内容管理系统,以允许你的用户去编辑他们的内容。(例如,为一个标记为 “已发布” 的文章,增加一些输入框和过滤)。

如果你想去了解更多内容,Django 美女的教程 中关于 the ORM 的节有详细的介绍。在 Django project website 上也有丰富的文档。

(题图 Christian Holmér,Opensource.com 修改. CC BY-SA 4.0


作者简介:

Katie McLaughlin - Katie 在过去的这几年有许多不同的头衔,她以前是使用多种语言的一位软件开发人员,多种操作系统的系统管理员,和多个不同话题的演讲者。当她不改变 “世界” 的时候,她也去享受烹饪、挂毯艺术,和去研究各种应用程序栈怎么去处理 emoji。


via: https://opensource.com/article/17/11/django-orm

作者:Katie McLaughlin 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出