返回

文章详情

我对Django的热爱

Hacker News2026年8月6日 07:34

我写这篇文章的初衷是庆祝Django的那些部分,这些部分在我和Buttondown的大多数时间里一直非常有用并且持久。其中一个挑战是,我所描述的Django本身的一个基本资产:它的意见和结构正好适度,随着时间的推移,它变得几乎是看不见的。一开始,我很难仔细阅读我们的代码库并指出“所谓”的Django相关内容,因为应用程序的Django部分与那些单纯的Pythonic或商业逻辑方面融为一体。我看Buttondown并不是看到一个Django应用,而是看到一个结构良好的代码库,其中许多问题都是由比我更聪明的人解决的。比起其他任何东西,这就是我对Django的热爱。尽管听起来有些诗意,但这使得博客文章显得简短而乏味。因此,我带上了思考帽和X光眼镜,仔细观察:Django的哪些部分在过去几年中给我们带来了最长期的杠杆作用?1. 中间件Django的中间件抽象非常简单,因此非常强大。我认为像我这样的开发者,在中间件作为函数与中间件作为类的迁移过程中真正成长的人往往理所当然地认为,不管实际的Python原语是什么,Django中间件都是对请求/响应生命周期起作用的简单函数。它们只需遵循该协议,就可以在其中随心所欲。事实证明,这种请求钩子对于许多事情非常有用:根据子域将请求路由到正确的新闻稿、捕获UTM和引荐归属、设置内容安全策略头、记录页面浏览、将请求上下文绑定到我们的结构化日志中,以及——下面——印上已部署的构建版本。以下是印上每个响应的已部署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_<field>_change钩子并持久化过渡行。 ... class Meta: abstract = True ordering = (

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡