DeepSeek+Claude强强联手,使用AI驱动DjangoStarter 3.1框架升级

前言

上个月底培训了一周就没时间更新博客

上周有一些空闲时间,就继续体验最近很火的AI辅助编程

之前的文章中有说到我配置好了 VSCode + Cline 插件搭配本地部署的 DeepSeek 来实现AI辅助编程

参考: 开发者新选择:用DeepSeek实现Cursor级智能编程的免费方案

但 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
  • 增加更多的默认页面
相关推荐
程序趣谈3 小时前
算法随笔_74: 不同路径_1
数据结构·python·算法
Cheng_08293 小时前
LLM自动化评测
python
朱剑君4 小时前
用Python打造AI玩家:挑战2048,谁与争锋
人工智能·python
JM丫5 小时前
python基础
笔记·python
天才测试猿6 小时前
接口自动化测试用例
自动化测试·软件测试·python·测试工具·测试用例·接口测试·postman
千里码aicood6 小时前
【2025】基于python+django的驾校招生培训管理系统(源码、万字文档、图文修改、调试答疑)
开发语言·python·django
冷琴19966 小时前
基于python+django+vue.js开发的医院门诊管理系统/医疗管理系统源码+运行
vue.js·python·django
等风来不如迎风去7 小时前
【Pycharm】Pycharm无法复制粘贴,提示系统剪贴板不可用
ide·python·pycharm
jay丿7 小时前
Django 分页操作详解
数据库·django·sqlite