尝试
在一个平常的工作日下午,小琪在她的工位上尝试着刚刚发现的一个新工具——nanodjango。她觉得这个工具看起来挺有趣的,想要看看它是不是真的能让开发变得更简单。
小胖那天提前完成了手头的任务,走到小琪的工位旁边,看到她在屏幕上捣鼓着什么。“嘿,小琪,你在忙什么呢?”小胖好奇地问道。
“哦,小胖,来看看这个,”小琪说,“我刚发现了个叫 nanodjango 的东西,可以在一个文件里完成整个 Django 应用,感觉挺有意思的。”
小胖凑近了一点,看了一眼屏幕上的代码,然后笑着说:“哇,你这个django正不正宗,怎么看起来像flask?”
小琪笑了笑回答:“是啊,但它其实是基于 Django 的,只是更简化了。你看,我已经写了一个简单的计数器应用,它还能直接跑起来。”说着,小琪展示了她写的代码:
from django.db import models
from nanodjango import Django
app = Django()
@app.admin
class CountLog(models.Model):
# 标准 Django 模型,注册到管理后台
timestamp = models.DateTimeField(auto_now_add=True)
@app.route("/")
def count(request):
# 标准 Django 函数视图
CountLog.objects.create()
return f"<p>Number of page loads: {CountLog.objects.count()}</p>"
“真酷!”小胖点头说,“不过这样会不会少了点什么?我们平时都习惯用 manage.py 和那些标准命令了。”
“刚开始我也这么想,”小琪解释道,“但其实它支持很多 Django 的特性,比如模型、视图和管理后台。而且,如果你的应用变大了,还能轻松转换成完整的 Django 项目。”
“那确实不错。”小胖表示赞同,“你这个计数器怎么工作的?”
小琪给小胖演示了一下如何通过访问主页增加计数,以及如何通过 API 获取当前计数,并补充了API端点的代码:
@app.api.get("/add")
def add(request, a: int, b: int):
# Django Ninja API 支持内置
CountLog.objects.create()
return {"count": CountLog.objects.count(), "sum": a + b}
“有意思,”小胖眼睛一亮,“我应该怎么开始使用它呢?”
小琪指着屏幕上的注释说道:“首先,我们需要安装 nanodjango。你可以用 pip 来安装它,就像这样:”
pip install nanodjango
小胖立刻在自己的终端上运行了这条命令,几秒钟后安装完成。“太棒了,接下来呢?”
“接下来就是编写我们的应用代码,”小琪说,“我已经写好了大部分内容。最后一步是保存这个文件,比如命名为 counter.py,然后我们可以用下面的命令来启动它:”
nanodjango run counter.py
小胖照做了,果然,一个本地服务器成功启动,他可以通过浏览器访问页面并测试计数功能,同时还执行了django默认的migrations,默认使用的是sqlite数据库。
“如果我想让它支持异步请求怎么办?”小胖突然想到一个问题。
小琪微笑着回应:“nanodjango 也支持异步视图,看这里:”
@app.route("/slow/")
async def slow(request):
import asyncio
await asyncio.sleep(10)
return "Async views supported"
接着,小琪继续介绍 nanodjango 对 API 的支持:“你知道吗?nanodjango 内置了对 Django Ninja 的支持,使得构建 RESTful API 更加容易。例如,我们可以定义一个简单的 API 端点如下:”
from ninja import Schema
class Item(Schema):
foo: str
bar: float
@app.api.post('/do_something')
def do_something(
request,
item: Item,
file: app.ninja.UploadedFile = app.ninja.File(...)
):
# 处理上传的文件和数据
return {"message": "Processing completed"}
小胖点了点头,表示理解:“这看起来很方便,特别是当我们需要快速搭建一些原型或小型应用时。”
小琪又提到:“对于更复杂的 API,我们可以直接使用 app.ninja 属性来访问额外的功能,而不需要直接导入 Django Ninja。这是为了避免某些导入顺序的问题。”
小胖对此感到好奇:“为什么不能直接导入 Django Ninja 呢?”
“这是因为 ninja 模块在导入时会尝试访问 Django 设置,而在 nanodjango 中所有配置都是在一个文件里完成的。如果我们先初始化 Django(),然后再导入 ninja,就不会有问题了。但是为了保持代码整洁,推荐使用 app.ninja 这个辅助属性。”
小胖若有所思地点点头,明白了其中的道理。
管理后台
“说到管理后台,”小琪继续道,“在 nanodjango 中,只要我们用 @app.admin 装饰器装饰模型,或者在设置中指定 ADMIN_URL,管理后台就会自动启用。”
她展示了如何注册一个模型到管理后台:
@app.admin(list_display=["id", "timestamp"], readonly_fields=["timestamp"])
class CountLog(models.Model):
timestamp = models.DateTimeField(auto_now_add=True)
“如果模型比较复杂,我们也可以按照标准的 Django 方式注册自定义的 ModelAdmin 类。”小琪补充道。
from django.contrib import admin
class CountLogAdmin(admin.ModelAdmin):
list_display = ["id", "timestamp"]
readonly_fields = ["timestamp"]
admin.site.register(CountLog, CountLogAdmin)
两人聊得越来越起劲,开始讨论起可以使用 nanodjango 来改进哪些工作流程,甚至设想了一些新的项目想法。他们还一起探讨了如何将这个工具集成到他们的日常工作中,比如创建内部使用的统计页面或自动化测试环境。
结尾
几天后,小胖和小琪利用 nanodjango 完成了一个小工具,并向团队展示了它的潜力。此外,当他们需要将项目从单文件转换为完整的 Django 项目时,只需使用以下命令:
nanodjango convert counter.py path/to/site --name=counter
这使得他们的应用能够随着业务需求的增长而扩展,保持灵活性的同时不失稳定性。
https://github.com/radiac/nanodjango
欢迎大家关注我的公众号~