前言
上个月底培训了一周就没时间更新博客
上周有一些空闲时间,就继续体验最近很火的AI辅助编程
之前的文章中有说到我配置好了 VSCode + Cline 插件搭配本地部署的 DeepSeek 来实现AI辅助编程
但 Cline 插件消耗 token 太快了,换本地部署的 DeepSeek 的话不够聪明
我后面又换了 RooCode 、 Continue 这俩插件,还有试了一下新的IDE Trae
用下来 RooCode 还不错,这是 Cline 的 fork 版本,功能多了一些,消耗 Token 数量我没去统计,感觉可能差不多
大模型服务我选择了购买 DeepSeek 和 Claude 的 API
Trae 胜在免费,不过国内外区别对待是有点让人难受的
最终我在 Claude 和 DeepSeek 的辅助下,完成了 DjangoStarter 3.1 版本的开发
关于 DjangoStarter
DjangoStarter v3 是下一代 Django 项目快速开发模板,专为提升开发效率和性能而设计。
结合了 Django 的丰富功能和 Django-Ninja 的性能、灵活、简洁特性,v3 版本旨在为开发者提供一个更加强大、简洁和高速的开发体验。
通过这个全新的框架版本,开发者能够迅速搭建起符合现代 web 应用标准的项目基础架构。
之前我写了一篇文章专门介绍这个v3版本,这里就不赘述了。
感兴趣的同学可以查看: 关于正在开发中的DjangoStarter v3版本
重构界面
本次最大的改变就是使用 Tailwind CSS 取代了原本的 Bootstrap,并且加入了很多新的页面,比如用户中心、设置、关于、联系我们、登录、注册、用户协议等,基本就是往 CMS 的方向走。
我甚至一度想引入 wagtail ,不过后面想想还是算了,已经够重了,等下完全和小项目不沾边,哈哈哈😄
国际化支持 (beta)
这次还添加了国际化支持
Django 本身是有国际化功能的
只不过很多项目都去除了
这次我加入了国际化支持,不过只是测试版,只是添加了支持,翻译部分我还没做好,所以也就还没把切换语言的按钮加上。
以下是一些国际化功能的用法
在模板里
django
{% translate 'Home' %}
在python代码里
python
from django.utils.translation import gettext_lazy as _
print(_('hello'))
生成翻译文件
在 src
目录下执行
bash
django-admin makemessages -l [language_code]
language_code:
- zh_HAns
- en_US
其他语言可以参考Django官网
编译消息文件
依然是在 src
目录下执行
bash
django-admin compilemessages
Windows 开发环境
如果是使用 windows 开发,需要先安装 gettext
工具
推荐使用 scoop 包管理器
bash
scoop install gettext
安装完成之后,执行以下命令验证
bash
xgettext --version
部分界面截图
旧版主页
先来看看旧版的主页长什么样

新版主页
新的界面使用 Tailwind CSS 重构,好看了很多

底部也是可以配置的

关于
这个页面做了很多动效,可以看看后面的动图

动效是用AOS做的,感觉还不错,挺方便的,不过要注意得使用 3.0 的 beta 版本,一开始没注意遇到了不少坑。

联系我们
这些联系方式都是可以配置的

表单也用上了 DjangoStarter 新版封装好的 BaseModelForm

封装好的 BaseModelForm 用起来是这样
python
class ContactModelForm(BaseModelForm):
class Meta:
model = Contact
fields = ('name', 'email', 'phone', 'message')
widgets = {
'name': forms.TextInput(attrs={'placeholder': '请输入您的姓名'}),
'email': forms.EmailInput(attrs={'placeholder': '请输入您的邮箱'}),
'phone': forms.TextInput(attrs={'placeholder': '请输入您的联系电话'}),
'message': forms.Textarea(attrs={'placeholder': '请输入您的留言内容', 'rows': 4})
}
登录/注册
这个登录页面是之前使用 wagtail 那个项目里面搬过来的

注册页面也是类似的,这里就不贴图片了
个人中心
个人中心这里的布局来自之前的 TodayTV 项目,不过原来也是从其他在线模板参考来的,界面不是很好看。
然而我用 Claude 3.5 和 DeepSeek R1 反复优化多次,仍然无法让我满意,而且代码越来越乱,感觉后面还是得自己来改。

下面的关于我

修改资料
这也是从 TodayTV 项目来的,搭配 Django Forms 实现出来的效果还可以。

隐私政策
这个是用 Claude 生成的,使用 RooCode 优化的提示词,看着有模有样的。

服务条款也是类似的,这里我就不截图了。
Demo页面
为了方便演示各种功能,我还新增了Demo页面
当然这个不太协调的页面是 AI 辅助布局的

错误页面
并且用 Claude 生成了几个错误页面
包括403、404、500页面,都是类似的,这里我只贴403页面的截图

解决了一个 issue
https://github.com/Deali-Axy/DjangoStarter/issues/20
有用户反馈本来应该返回400的接口,实际返回了200
我看了之后发现这个问题属于是从DRF迁移到ninja的历史遗留问题
之前我在框架里封装 responses 用于快捷输出各种返回状态
python
def ok(message: str, data: Optional[dict] = None):
return _gen_resp(message, data, 200)
def forbidden(message: str, data: Optional[dict] = None):
return _gen_resp(message, data, 403)
def bad_request(message: str, data: Optional[dict] = None):
return _gen_resp(message, data, 400)
def not_found(message: str, data: Optional[dict] = None):
return _gen_resp(message, data, 404)
但现在 ninja 里,一直返回的都是 200,这个就是处理返回状态码的地方出问题。
有几种解决思路,反正原本我用重写 renderer 的方式是没办法的,renderer里没法定义返回值,只能改变相应内容。
要不就是用 django 中间件,但需要解析 JSON 会影响性能
最终我对 responses 进行了改造,新增了 ResponseGenerator
这个类,代码就不贴了
关键实现就是用了 ninja 的 api.create_response
这个方法可以指定 status code
在需要用到的地方,比如 src/apps/account/apis/auth/apis.py
python
router = Router(tags=['auth'])
_resp = ResponseGenerator(router=router)
@router.post('/register', url_name='account/auth/register')
def register(request, data: RegisterSchema):
if User.objects.filter(username=data.username).exists():
return _resp.bad_request(request, '用户名已存在!')
if data.phone:
phone_pattern = '^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$'
if not re.match(phone_pattern, data.phone):
return _resp.bad_request(request, '手机号码格式不对!')
if UserProfile.objects.filter(phone=data.phone).exists():
return _resp.bad_request(request, '手机号已存在!')
if data.password != data.confirm_password:
return _resp.bad_request(request, '密码不一致!')
相比起原来的,每个返回的响应需要添加 request 参数
虽然比起原来复杂一点,也算是搞定了。
Todos
- https://django-ninja.cn 上有不少 ninja 周边生态组件,后续可以用上
- 将 admin 由 simpleui 切换到 unfold admin
- 增加更多的默认页面