首页 时政热点 科技头条 智能AI 安全攻防 数码硬件 开发者生态 汽车 游戏 社会热点 开源推荐 医疗健康 归档 标签 关于

我喜欢 Django 的原因

摘要

My goal at the onset of writing this essay was to celebrate the parts of Django that I, in Buttondown writ large, have found so useful and so enduring over the years. One of the challenges in doing th...

the and that Django request this over what structured things
2026-08-06 1 阅读 约8分钟阅读 j4mie
分享:
字号:
我开始写这篇文章的目的是庆祝 Django 的部分,我在 Buttondown 中发现这些部分多年来非常有用且经久不衰。这样做的挑战之一是我所描述的 Django 本身的一项基本资产:它的固执己见和结构化程度恰到好处,随着时间的推移,它变得不可见。我发现一开始很难眯着眼睛查看我们的代码库并指向“引用-不引用”Django 的东西,因为应用程序的 Django 部分如此顺利地融入了简单的 Pythonic 或简单的业务逻辑方面。我看 Buttondown 时看到的并不是一个 Django 应用程序;而是一个 Django 应用程序。我看到了一个结构良好的代码库,其中有许多事情已经由比我更聪明的人解决了。这就是我喜欢 Django 的最重要的一点。无论这可能多么富有诗意,它都会成为一篇简短而无聊的博客文章。所以我戴上思维帽和X光护目镜,真正地审视一下:Django的哪些部分在过去几年里给我们带来了最长期的影响力? 1. 中间件 Django 的中间件抽象非常简单,因此非常强大。我认为像我这样在中间件即函数与中间件即类迁移过程中真正成熟的人理所当然地认为,无论实际的 Python 原语如何,Django 中间件都是作用于请求/响应生命周期的简单函数。他们所需要做的就是采用该协议,他们可以在其中做任何他们想做的事情。事实证明,这种请求挂钩对于很多事情都非常有用:根据其子域将请求路由到正确的新闻通讯,捕获 UTM 和引荐来源网址属性,设置 Content-Security-Policy 标头,记录页面浏览量,将请求上下文绑定到我们的结构化日志上,以及在下面标记已部署的构建版本。下面是用部署的 git SHA 标记每个响应的完整内容,因此过时的浏览器选项卡可以注意到已发布较新的版本: # app/emails/middlewares/build_version.py class Middleware : def __init__ ( self , get_response : Callable[[HttpRequest], HttpResponse]) -> None : self .get_response = get_response def __call__ ( self , request : HttpRequest) -> HttpResponse: response = self .get_response(request) if settings.HEROKU_SLUG_COMMIT and not flag_is_active(CIRCUIT_BREAKER_FLAG): response[BUILD_VERSION_HEADER] = settings.HEROKU_SLUG_COMMIT return response 如果有一种工具我认为中等 Django 开发人员应该更多地利用,那就是中间件。 2. 模型(和轻量继承) 我们回避多态模型,部分原因是我们认为它们有点像一把枪,但更现实的是,我们没有太多适合它们的用例。但是,Buttondown 中的每个模型都继承自基本模型。它的修剪版本如下所示: # app/utils/models.py class BaseModel ( models . Model ): Creation_date = models.DateTimeField( auto_now_add = True ) id = models.UUIDField( Primary_key = True , default =uuid.uuid4, editable = False ) objects = TypeIDAwareManager() def save ( self , * args , ** kwargs ): super ().save(*args, **kwargs) # 对于任何实际更改的跟踪字段,触发其 #handle__change 挂钩并保留过渡行。 ... class Meta : abstract = True ordering = ( "-creation_date" ,) 该基类正在悄悄地做很多事情,所有这些都是选择加入和附加的:每个表上的 UUID 主键和creation_date 都是免费的。 ORM 通过自定义管理器和查询集透明地解码公共的、类型前缀的 ID( sub_... 、 em_... )。隐式更改跟踪:定义handle__change,只要该字段发生更改,它就会运行 - 无信号,无需注册。持久来源:将字段映射到转换表,并且每个更改都写入其自己的行。每个字段验证挂钩 ( validate_ )。一个选择加入的软删除管理器,并连接到我们的数据完整性检查系统。在这篇文章中出现似乎是一件奇怪的事情,但 Django 的面向对象方法的便利之处在于,所有这些都是零碎的。嫁接新的通用功能不需要任何大量的劳动力或迁移或重构。这意味着能够对新字段进行来源跟踪之类的事情非常非常简单 - 模型选择使用单个方法,而基类则完成其余的工作: # app/emails/models/email/model.py class Email ( BaseModel ): # 隐式更改跟踪:定义handle__change 和 BaseModel # 每当该字段实际更改时调用它。没有信号,没有接线。 def handle_body_change ( self , ** kwargs ) -> None : AsynchronousAction.enqueue(sync_snippet_references, [ str ( self .id)]) # 持久来源:将字段映射到转换表,并且每个更改都作为一行持久保存。加一就是单行字典条目。 @classmethod def tracked_field_to_transition_class ( cls ) -> dict[ str , type[BaseTransition]]: r
这篇文章对您有帮助吗?

订阅66必读

每日精选科技资讯,直达你的邮箱