作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
Alex和r Shurigin
验证专家 在工程
9 的经验

亚历山大喜欢从零开始创建和构建专家应用程序. 他擅长使用Python、PHP和JavaScript解决问题.

阅读更多
分享

在本教程中, 我们将看看Django开发人员经常犯的一些常见错误以及避免这些错误的方法. 即使你是一个熟练的Django开发人员,本教程也很有用, 比如在静态资产中维护难以管理的大型设置或命名冲突, 不仅仅局限于第一次接触Django的新开发者.

Django是一个免费的开源Python web框架,它帮助解决了常见的开发挑战,并允许您灵活地构建, 结构良好的应用程序. Django有很多现成的现代特性. 就我个人而言, 管理, 对象关系映射工具(ORM), 路由, 和模板特性使Django成为我的第一选择,因为应用程序需要大量的工作, 而我和其他开发者一样喜欢我的工作, 我想在这些基本的重复性任务上花尽可能少的时间. Django允许你在不牺牲灵活性的情况下完成所有这些.

Django的杀手级特性是一个强大的可配置管理界面,它可以自动构建?)从你的模型的模式和管理面板模型,让你感觉像一个向导. 通过Admin界面, 用户可以配置很多东西,包括访问控制列表(ACL)。, 行级权限和操作, 过滤器, 订单, 小部件, 形式, 额外的URL帮助程序, 以及任何你能想到的东西. 我相信每个应用程序都需要一个管理面板——如果还没有的话, 这只是一个时间问题,直到您的基本应用程序需要一个. 使用Django 管理,你可以快速灵活地创建一个.

Django有一个强大的ORM,可以与所有主流数据库兼容. 由于它是惰性的,所以与其他orm不同,它只在需要时访问数据库. 它支持所有主要的SQL指令(和函数),您可以从Python源代码中使用这些指令(和函数),并且由于Python的特性而感觉非常舒适.

Django的模板引擎既灵活又强大. 你可以使用很多标准 过滤器和标签 以及为您的项目创建新的自定义过滤器和标签. 除了Django模板,Django还支持其他模板引擎, 它还提供了一个API,可以通过模板处理的标准快捷功能轻松集成其他模板引擎.

Django还有很多其他重要的特性,比如URL路由器,它可以解析传入的请求,并从路由器模式中构建新的URL. 总的来说,Django框架是一种愉快的体验,无论何时你需要帮助,只要阅读 文档.

错误没有. 1:为项目依赖项使用全局系统Python环境

不要对项目依赖项使用Python的全局环境, 因为它会产生依赖冲突. Python不能同时使用多个包版本. 如果不同的项目需要同一包的不同不兼容版本,这可能是一个问题.

这个错误通常是由不了解Python的环境隔离特性的新Python和Django开发人员犯的.

有很多方法可以隔离您的环境,但最常见的方法是:

  • virtualenv: 一个Python包,它生成一个Python环境文件夹,并具有用于[de]激活环境和管理环境中已安装的Python包的脚本. 这是我最喜欢的方法,因为这是做这项工作最简单的方法. 通常,我在项目文件夹附近创建环境.
  • virtualenvwrapper: 一个全局安装的Python包,并提供用于创建/删除/激活等的工具集. 虚拟环境. 所有虚拟环境都存储在一个文件夹中(可以通过环境变量WORKON_HOME覆盖该文件夹)。. 我看不出使用它有什么好处 virtualenvwrapper 而不是 virtualenv.
  • 虚拟机(VM): 没有比专用于您的应用程序的整个虚拟机更好的隔离了. 有很多工具可供选择,包括 VirtualBox (免费), VMware, 相似之处, Proxmox (我个人最喜欢的,它有一个免费版本). 结合虚拟机自动化工具,如 流浪的,这可能是一个非常强大的解决方案.
  • 容器: 在过去的几年里,我一直在使用 码头工人 在几乎每一个项目中,尤其是在每一个我从头开始的新项目中. 码头工人是一个了不起的工具,它提供了很多特性,并且有很多用于容器自动化的第三方工具. 它有一个层缓存功能,这使得重新构建容器非常快. 在容器中, 我使用全局系统Python环境, 因为每个容器都有自己的文件系统,并且项目在高层上是隔离的. 码头工人允许新的团队成员更快地开始项目工作, 特别是如果他们有码头工人的经验.

要我说,我更喜欢 virtualenv 用于项目依赖隔离和管理的Python包和码头工人容器.

错误没有. 2:没有将项目依赖关系固定在 需求.文本文件。 文件

每个新的Python项目都应该以 需求.文本文件。 文件和一个新的隔离环境. 通常通过 皮普/ easy_install 但别忘了把它们加到你的 需求.文本文件。 文件太. 这使它更容易(可能的 (更合适)将项目部署到服务器上, 或者让团队成员在自己的机器上启动项目.

此外,同样重要的是 中的依赖项的特定版本 需求.文本文件。 文件. 通常, 不同版本的包提供不同的模块, 功能, function parameters; even a minor version change in a dependency can break your package. 这是一个非常严重的问题,如果您的项目是实时的,并且您此后定期安排部署, 没有版本控制, 您的构建系统将始终安装软件包的最新可用版本.

始终为生产固定您的包! 就我个人而言,我使用一个非常好的工具,叫做 pip-tools 哪个能帮我做这个. 它提供了一组命令行工具来帮助管理依赖项. 它会自动生成 需求.文本文件。 它不仅固定了你的依赖,还固定了你的整个依赖树, 其中包括依赖项的依赖项.

有时, 您只希望更新依赖项列表中的一些包(例如, 只有Django/Flask/任何框架或工具), 如果使用“pip freeze”,则不知道哪个包对应哪个依赖项, 所以你不能升级依赖项. 与pip-tools, 然而, 它会根据您固定的依赖项自动固定包, 因此,它会自动解析哪些包需要更新. 作为奖励, 您还可以确切地知道哪个包来自哪个依赖项,因为它是如何用注释标记它们的 需求.文本文件。 文件.

为了谨慎起见,最好也备份依赖项源文件! 在文件系统中保留一份副本, git管理的文件夹, S3文件夹, FTP, SFTP-w在这里ver, 但要把它放在手边. 曾经有过这样的例子 一个相对较小的未列出的包破坏了NPM上的大量包. Pip提供了一个工具,可以将所有必需的依赖项作为源文件下载, 通过跑步阅读更多内容 PIP帮助下载.

错误没有. 3:使用旧式Python函数而不是基于类的视图

有时在应用程序中使用一个小的Python函数是个好主意 的观点.py 文件,特别用于测试或实用程序视图, 但一般来说, 您应该在应用程序中使用基于类的视图(cbv).

cbv是提供抽象类的通用视图,这些抽象类实现了由专业人员构建的通用web开发任务,并涵盖了所有通用行为. 他们有一个很棒的结构化API, 当您使用cbv时,您可以使用面向对象编程的所有优点. 它使您的源代码更加清晰易读. 忘记为清单使用Django标准视图函数的痛苦吧, CRUD操作, 形式的处理, 等. 你只是扩展合适的CBV为您的视图和覆盖类属性或函数(通常一个函数返回一个属性,你可以添加任何逻辑那里面条从你的源代码中使用视图函数而不是CBV的情况下)配置视图行为.

例如, 你可以在你的项目中有不同的混合,覆盖基本的CBV行为来构建视图上下文, 在行级别检查授权, 从应用程序结构自动构建模板路径, 集成智能缓存, 和更多的.

我构建了一个名为 Django模板名称, 哪个基于应用程序名称和视图类名称来标准化视图的模板名称. 我每天都用它,它节省了我发明名字的很多时间. 简单地把混合在你的CBV -类细节(TemplateNames, DetailView):它将开始发挥作用! 当然, 你可以覆盖我的功能,并添加移动响应模板, 不同的用户代理模板, 或者任何你想要的东西.

错误没有. 4:写胖视图和瘦模型

在视图而不是模型中编写应用程序逻辑意味着您已经将属于模型的代码编写到视图中, 让模特变“胖”,让模特变“瘦”.”

你应该写胖模型,瘦视图.

将逻辑分解为模型上的小方法. 这允许您从多个来源(管理界面UI)多次使用它, 前端用户界面, API端点, 多个视图)在几行代码中,而不是复制粘贴大量的代码. 下次你给用户发邮件的时候, 使用电子邮件功能扩展模型,而不是在控制器中编写此逻辑.

这也使您的代码更容易进行单元测试,因为您可以在一个地方测试电子邮件逻辑, 而不是在每个控制器中重复发生这种情况.

你可以在 Django最佳实践 项目. 解决方案很简单:编写胖模型和瘦视图, 所以让我们在你的下一个项目中做这件事(或者重构你当前的项目).

错误没有. 5:一个巨大的,难以管理的设置文件

即使是新的 Django项目设置文件 有很多设置吗. 在一个真实的项目中, 一个设置文件增长到700多行配置,并且将变得难以维护, 尤其是当你的开发者, 生产, 而登台环境都需要定制配置.

您可以手动划分配置文件并创建自定义加载器, 但我想向您介绍一个很好的、经过良好测试的Python包, Django拆分设置,是我与人合著的.

该包提供两个函数-可选包括-它支持通配符的路径和导入配置文件在相同的上下文中, 使用先前加载的文件中声明的配置项构建配置变得简单. 它不会影响Django的性能,你可以在任何项目中使用它.

看看最小配置示例:

从split_设置.工具导入可选,包括

包括(
    的组件/基础.py',
    的组件/数据库.py',
    的组件/ *.py',

    #项目不同环境设置
    可选(“env /猛击/ *.py'),
    可选(“env /生产/ *.py'),
    可选(“env /临时/ *.py'),
    
    #用于任何本地设置
    可选(“local_设置.py'),
)

错误没有. 6:一体化应用,应用结构不合理,资源放置不正确

任何Django项目都由多个应用程序组成. 在Django符号中,an 应用程序 是一个Python包,它至少包含 __init__.py模型.py 文件; in the latest Django versions, 模型.py 不再需要. __init__.py 就足够了.

Django应用程序可以包含Python模块, Django-specific模块 (观点, url, 模型, 管理, 形式, 模板标签, 等), 静态文件, 模板, 数据库迁移, 管理命令, 单元测试, 和更多的. 您应该将您的整体应用程序分成小的, 可重用的应用程序 使用简单的逻辑. 你应该能够用一两个简短的句子描述应用程序的整个目的. 例如:“允许用户通过电子邮件注册和激活他们的帐户.”

这是一个好主意是调用项目文件夹 项目 把申请放到 项目/应用程序/. 然后,将所有应用程序依赖项放入它们自己的子文件夹中.

例子:

  • 静态文件: 项目/应用程序/浏览器名称/静态/浏览器名称/
  • 模板标签: 项目/应用程序/浏览器名称/ templatetags /浏览器名称.py
  • 模板文件: 项目/应用程序/浏览器名称/模板/浏览器名称/

始终在子文件夹中添加应用程序名称的前缀,因为所有静态文件夹都合并到一个文件夹中, 如果两个或多个应用程序有 js /核心.js 文件,最后一个应用程序 设置.INSTALLED_APPLICATIONS 会推翻之前的吗. 我曾经在当前的项目中遇到过这个bug,并浪费了大约6个小时的调试时间,直到我意识到另一个开发人员已经覆盖了这个bug 静态/ 管理 / js /核心.js 因为该团队正在实现自定义SPA管理面板,并以相同的方式命名他们的文件.

下面是一个门户应用程序的示例结构,该应用程序有很多资源和Python模块.

root@c5b96c395cfb:/test# tree 项目/应用程序/ portal /
项目/应用程序/ portal /
├──__init__.py
├──管理.py
├──应用.py
├──管理
│├──__init__.py
││──命令
│├──__init__.py
│├──update_portal_feeds.py
├──迁移
││├──__init__.py
├──模型.py
├──静态
││──传送门
│├──CSS
│├──├
│       └── js
├──模板
││──传送门
││──索引.html
├──templatetags
│├──__init__.py
││──传送门.py
├──测试.py
├──url.py
└──的观点.py

11个目录,14个文件

使用这样的结构, 您可以随时将应用程序导出到另一个Python包中并再次使用它. 您甚至可以将其作为开放源代码包发布到PyPi中,或者将其移动到另一个文件夹中.

你最终会得到这样一个项目结构:

root@c5b96c395cfb:/test# tree -L
.
├──部署
│├──├
││├──docker
│├──├
│├──制作效果
├──文档
├──日志
├──管理.py
├──媒体
├──项目
│├──__init__.py
│├──apps
││├──├
││├──blog
││├──rammstein
││├──rammstein
││├──├
││──用户
│├──cat
│├──设置.py
│├──├─├
│├──模板
│├──urls.py
│├──wsgi.py
└──静态
    └──管理
        ├──css
        ├──字体
        ├──img
        └── js

25个目录,5个文件

在一个真实的项目中, 当然, 它会更加复杂, 但这种结构使事情更简单、更清晰.

错误没有. 7: STATICFILES_DIRSSTATIC_ROOT 迷惑新手Django开发者

STATICFILES_DIRS? STATIC_ROOT?

静态文件是指在应用使用过程中不会发生变化的资产.g., JavaScript, CSS,图像,字体等. 在Django中,它们只在部署过程中被“收集”到一个公共目录中.

〇发展模式python管理.py runserver-Django使用 STATICFILES_FINDERS 设置. 列表中列出的文件夹中查找所请求的静态文件 STATICFILES_DIRS 设置. 如果失败,Django会尝试使用 django.普通发布版.静态文件.发现者.AppDirectoriesFinder,它在 静态 项目中每个已安装应用程序的文件夹. 这允许您编写可重用的应用程序,这些应用程序附带它们自己的静态文件.

在生产环境中,你可以使用像Nginx这样的独立web服务器来提供静态服务. web服务器不知道Django项目应用程序的结构,也不知道静态文件分布在哪个文件夹中. 幸运的是,Django提供了collect静态管理命令 python管理.py collect静态,它穿过 STATICFILES_FINDERS 并从应用程序复制所有静态文件 静态 中列出的文件夹和文件夹 STATICFILES_DIRS 目录中指定的目录 STATIC_ROOT 设置. 这允许使用与Django开发模式服务器相同的逻辑解析静态文件资源,并将所有静态文件放在web服务器的一个地方.

别忘了跑步 collect静态 在您的生产环境中!

错误没有. 8:默认 STATICFILES_STORAGEDjango模板加载器

STATICFILES_STORAGE

让我们谈谈生产环境资产管理. 我们可以提供最好的用户体验,如果我们使用“资产永不过期”的政策(你可以阅读更多关于 在这里). 这意味着我们所有的静态文件都应该被web浏览器缓存数周、数月甚至数年. 换句话说,您的用户应该只下载您的资产一次!

那很酷, 我们可以在Nginx配置中为静态文件文件夹设置几行代码, 但是缓存无效呢? 如果用户只下载我们的资产一次, 如果你更新了你的标志会发生什么, 字体, JavaScript, 或者菜单中项目的文本颜色? 为了绕过这个问题,您应该为每个部署上的静态文件生成唯一的url和文件名!

我们可以简单地用 ManifestStatic文件sStorage as STATICFILES_STORAGE (注意,散列只在 DEBUG = false 模式)并运行 collect静态 上面讨论的管理命令. 这将减少对您的生产网站的资产请求计数,并使您的网站渲染得更快.

缓存Django模板加载器

另一个很酷的Django特性是缓存模板加载器, 在每个模板渲染上都不会重新加载和解析模板文件. 模板解析是一项非常昂贵的操作,需要使用大量资源. 默认情况下, Django模板在每次请求时都会被解析, 但这很糟糕, 特别是在生产过程中, 在哪里可以在短时间内处理数千个请求.

请查看 缓存.加载程序 配置部分提供了一个很好的示例,并详细说明了如何做到这一点. Don’t use the loader in development mode because it doesn’t reload parsed 模板 from the 文件 system; you will need to restart your 项目 using python管理.py startapp 每次修改模板时. 这在开发过程中可能很烦人,但对于生产环境来说是完美的.

错误没有. 9:用于实用程序或脚本的纯Python脚本

Django提供了一个非常好的特性,叫做 管理命令. 只需使用它,而不是重新发明轮子并为您的项目实用程序编写原始Python脚本.

另外,请查看 Django的扩展 包,它是Django的自定义扩展的集合. 也许有人已经实现了您的命令! 已经有很多常见的任务命令.

错误没有. 10 .重新发明轮子

不要重新发明轮子

Django和Python有数千种现成的解决方案. Try Googling before you write something that is not unique; t在这里’s probably a feature-rich solution that already exists.

试着把事情简单化. 谷歌第一次! 安装, 配置, 扩展, 如果你找到一个高质量的包,就集成到你的项目中, 当然, 当你有机会的时候为开源做贡献.

首先,这里是我自己的Django公共包列表:

  • Django宏 通过使用宏,可以很容易地在Django应用程序中编写(和读取)URL模式.
  • Django模板名称 是一个小的混合,它允许您轻松地标准化您的CBV模板名称.
  • django-split-设置 让你将Django设置组织到多个文件和目录中. 轻松覆盖和修改设置. 在设置文件路径中使用通配符,并将设置文件标记为可选.

不要重复自己(DRY)!

I really like DRY methodology; that’s why I created Django框架 作为一个便利的工具,它有一些非常简洁的功能:

  • 用于开发/生产的码头工人镜像, 由docker-compose管理, 哪一种方法可以让您轻松地编排容器列表.
  • 用于生产部署的简单Fabric脚本.
  • 的配置 Django拆分设置 包含基本和本地源设置的包.
  • Webpack集成到项目中-只有 经销 文件夹将被Django收集 collect静态 comm和.
  • 在生产环境中配置所有基本的Django设置和特性,比如可缓存的Django模板, 散列静态文件, 集成调试工具栏, 日志记录, 等.

它是一个随时可用的Django骨架,为你的下一个项目从零开始, 希望, 通过引导项目为您节省大量时间. Webpack有最小的基本配置,但它也安装了预配置的SASS来处理 .scss 文件.

聘请Toptal这方面的专家.
现在雇佣
Alex和r Shurigin

Alex和r Shurigin

验证专家 在工程
9 的经验

瓦伦西亚,西班牙

2016年7月4日加入

作者简介

亚历山大喜欢从零开始创建和构建专家应用程序. 他擅长使用Python、PHP和JavaScript解决问题.

阅读更多
作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

Toptal开发者

加入总冠军® 社区.