关于正在开发中的DjangoStarter v3版本
前言
最近做的这个项目大量使用了 python 及其相关的生态,因此自然而然选择了我的 DjangoStarter 作为后端框架
之前 v2 版本是用 RestFramework 做接口的,后面我试用了一次 django-ninja 之后就喜欢这种类似 FastApi 的写接口方式
正所谓天下苦 drf 久矣,在新的 v3 版本框架中,我决定直接把整个 RestFramework 替换成 ninja
目前大部分功能都完成了,代码在主项目的 v3-alpha 分支里,等开发完成我会合并到 master 里 (现在基本可用了)
另外还做了很多新功能和改进,接下来会介绍一下
关于 DjangoStarter
这个开发脚手架,最开始还是叫 DjangoRails ,名字模仿的 Ruby on Rails
后面经过重构才改成 DjangoStarter
这个脚手架起源于2020年开始的项目,当时使用 Django + RestFramework 作为后端框架,为了满足安全部门的要求,又做了很多魔改,再加上其他一些配置啥的,慢慢的就积累出了 DjangoStarter ~
这里贴一下项目介绍吧~
DjangoStarter v3 是下一代 Django 项目快速开发模板,专为提升开发效率和性能而设计。
结合了 Django 的丰富功能和 Django-Ninja 的性能、灵活、简洁特性,v3 版本旨在为开发者提供一个更加强大、简洁和高速的开发体验。
通过这个全新的框架版本,开发者能够迅速搭建起符合现代 web 应用标准的项目基础架构。
核心特性
- Django Ninja 集成:采用 Django Ninja 替代传统的 Django Rest Framework,为 API 开发带来了性能优化和更简洁的编码体验。利用 Python 类型提示,自动生成交互式 API 文档,不再需要 drf-yasg 那一堆繁琐的手动配置文档,同时提升了代码的可读性和维护性。
- 增强的安全性:内置了多项安全功能,包括但不限于 Admin 登录验证码、IP 限制等,确保应用的安全性。
- 代码自动生成:v3 版本进一步优化了代码生成器,丢掉了 DRF 这个包袱,只需要定义模型,就可以生成 schema 以及 RESTFul API,还能根据定义自动创建测试用例,大大提高开发效率。
- 随机种子数据生成:v3 版本内置 seed 模块,支持为已有模型自动填充假数据,方便开发测试。
- 模块化项目结构:推出了更加模块化的项目结构设计,方便开发者根据需要添加或移除功能模块,使项目维护更为简单。
- 现代化前端集成:提供了对现代化前端技术的集成,以及利用 NPM 和 gulp 管理前端资源,帮助开发者打造富交互式的用户界面。
- 容器化支持:内置 Dockerfile 和 docker-compose.yml 配置,简化了容器化部署的过程,支持一键部署到任何支持 Docker 的环境。
- 详尽的文档与社区生态:提供全面的文档和指南,覆盖从项目启动到部署的每一个步骤。同时,基于活跃的 Django 开源社区,开发者可以轻松获取支持和反馈。
关于v3版本
OK,终于说回正题
这次重构v3版本最主要的原因是把 RestFramework 替换成 ninja
然后也做了一些新的功能
比如:
- 新的自动代码生成功能
- 完善了单元测试和集成测试,搭配代码生成,可以为每个应用自动生成 crud 的测试用例
- 随机种子数据,目前使用 faker 实现假数据,打算进一步实现类似 EFCore 的种子数据机制,使假数据更自然
- 新的登录接口
- 多种第三方登录接入(目前接了微信、小程序、企微)
- 使用 tailwindcss 替换 bootstrap 实现前端(只是一些简单的后台展示,还是以 API 为主)
- 拆分 settings 配置,像 AspNetCore 那样支持多个环境配置
- 更换了包管理器
目前大概就这些吧
后面有用到什么新的再一步步加入
代码生成
一直没有好好介绍一下 DjangoStarter 框架的具体实现
代码生成这块其实也不复杂,包名是 django_starter.contrib.code_generator
主要就两个部分
- 分析器 -
src/django_starter/contrib/code_generator/analyzer.py - 生成器 -
src/django_starter/contrib/code_generator/generator.py
分析器使用 django.apps.apps 提供的 get_app_config 和 get_models 来扫描已注册的所有 App
然后搭配反射(或者在 Python 中应该叫自省 inspect)来获取各个字段的信息,把搜集到的信息保存到我定义的几个对象中
然后在生成器部分,根据特定的规则,使用 jinja2 模板进行渲染~
注意要把字段的 primary_key, is_relation 这些属性拿出来,后面有用。如果是关系字段(如外键)的话,还需要把 target_field 拿出来。
大概思路就是这样,其中有很多细节的地方,本文的篇幅受限,后续我写篇文章来介绍吧。
API
使用 ninja 来写 API
不同于之前的 RestFramework ,ninja 用的是装饰器来定义路径,这个对于不喜欢 Django 配置式路由的人来说很友好
项目结构我也做了一些调整
以 demo 应用为例
每个 model 都在 apis 下单独创建一个 package,单独有 apis.py 和 schemas.py 代码,这样不会把所有代码逻辑混在一起
PS:后续如果我转向使用 FastApi,也可以用这个思路来组织项目
demo
├─ tests
│ ├─ __init__.py
│ ├─ test_music_album.py
│ ├─ test_music.py
│ ├─ test_movie.py
│ └─ test_actor.py
├─ migrations
│ ├─ __init__.py
│ └─ 0001_initial.py
├─ apis
│ ├─ music_album
│ │ ├─ __init__.py
│ │ ├─ schemas.py
│ │ └─ apis.py
│ ├─ music
│ │ ├─ __init__.py
│ │ ├─ schemas.py
│ │ └─ apis.py
│ ├─ movie
│ │ ├─ __init__.py
│ │ ├─ schemas.py
│ │ └─ apis.py
│ ├─ actor
│ │ ├─ __init__.py
│ │ ├─ schemas.py
│ │ └─ apis.py
│ └─ __init__.py
├─ __init__.py
├─ views.py
├─ models.py
├─ apps.py
└─ admin.py
坑点
要说的话,ninja 这种比较新的库,还是有一点点坑的地方的
- 有些文档不够详细
- URL reverse 功能不够好用,只能在
NinjaAPI对象配置urls_namespace,下面的各级 router 都不能配置urls_namespace,我只能对下面的接口用url_name='demo/movie/list'这种形式的命名 - ModelSchema 对外键的支持有限,对于输入的 schema ,不能在 Meta.fields 里配置这个外键字段,需要自己单独写出来,这点对于自动生成代码来说有点麻烦,不过我已经解决了
种子数据/假数据
这个可以叫 seed data ,也可以叫 mock data
在开发测试中很有用,不用手动去添加各种数据
包名是 django_starter.contrib.seed
一开始我是找到了一个叫 django-seed 的库,可以实现种子数据的生成
不过这个包已经年久失修,好几年没更新了
我试了一下,运行起来居然还依赖 PostgreSql 的库?!
就离谱,不应该和数据库无关的吗……
算了,我自己写得了,又不难
Python 生态就是好,Faker 库用来生成随机假数据很好用
主要代码在 src/django_starter/contrib/seed/seeder.py 文件里
就是根据不同的字段类型,使用不同的假数据方法
坑点:外键
其中外键字段会比较坑,需要做一些特殊处理
related_model = field.related_model
# Ensure there is at least one instance of the related model
related_instance = related_model.objects.order_by('?').first()
if not related_instance:
related_instance = related_model.objects.create(**self.seed(related_model))
# Set the foreign key ID field
fake_data[field.attname] = related_instance.pk
settings 拆分
早就对 Django 的配置 settings.py 不爽了
项目一大,这个文件就乱七八糟又臭又长
而且还不支持多环境切换,得自己写一堆逻辑去判断不同环境
之前版本中,我是把几个主要的配置拆分成不同文件,然后在 settings.py 里引用
现在我用上了 django-split-settings 这个包,瞬间舒服了
来看看现在的 config 目录
config
├─ settings
│ ├─ environments
│ │ ├─ __init__.py
│ │ ├─ testing.py
│ │ ├─ production.py
│ │ ├─ local.py.template
│ │ └─ development.py
│ ├─ components
│ │ ├─ __init__.py
│ │ ├─ simpleui.py
│ │ ├─ rq.py
│ │ ├─ ninja.py
│ │ ├─ logging.py
│ │ ├─ django_starter.py
│ │ ├─ database.py
│ │ ├─ csp.py
│ │ ├─ cors.py
│ │ ├─ common.py
│ │ ├─ captcha.py
│ │ └─ caches.py
│ └─ __init__.py
├─ __init__.py
├─ wsgi.py
├─ urls_root.py
├─ urls.py
├─ env_init.py
├─ asgi.py
└─ apis.py
可以看到现在 settings 变成了一个 package
各种配置拆分出来分散到 components 下面
然后不同的环境又放到 environments 下面,可以覆盖前面定义的配置
很好的解决了之前的几个痛点
更换包管理器
原本就直接使用 pip ,搭配 requirements.txt 来管理依赖
这个方式的优缺点我就不多说了
这次换成 pdm ,总算有点现代包管理器的感觉了
PS:其实我之前还用过 poetry ,不过偶尔会遇到一些奇奇怪怪的问题,弃了~
小结
大概就这些吧,后面有什么新的想法我再来更新
还有其中几个关键的更新我可能会单独写文章来详细介绍~
关于正在开发中的DjangoStarter v3版本的更多相关文章
- 关于在.Net开发中使用Sqlite的版本选择问题
原文:关于在.Net开发中使用Sqlite的版本选择问题 如果一个.NET应用要自适应32位/64位系统,只需要在项目的“目标平台”设置为“Any CPU”.但是如果应用中使用了SQLite,情况就不 ...
- 【转】关于在.Net开发中使用Sqlite的版本选择问题
如果一个.NET应用要自适应32位/64位系统,只需要在项目的“目标平台”设置为“Any CPU”.但是如果应用中使用了SQLite,情况就不同了. SQLite的.NET开发包来自是System.D ...
- Java中的微信支付(1):API V3版本签名详解
1. 前言 最近在折腾微信支付,证书还是比较烦人的,所以有必要分享一些经验,减少你在开发微信支付时的踩坑.目前微信支付的API已经发展到V3版本,采用了流行的Restful风格. 今天来分享微信支付的 ...
- 【原】webapp开发中兼容Android4.0以下版本的css hack
话说现在的手机型号越来越多,主要还是android和ios这2个巨头称霸了江湖,而他们自带的浏览器内核是webkit,那对于做移动网页开发的同事来说,一般只要做好webkit内核浏览器的展现效果就行了 ...
- asp.net5开发中DNX SDK版本的影响
某次asp.net5开发中遇到了一个很奇怪的问题,引用部分的nuget包没有显示任何错误,如下图: 但是编译时出现了几百个错误: 错误基本都是形如“CS0246 The type or namespa ...
- android studio 开发中启动android项目报错sdk版本不一致解决方案
安卓项目开发中新建项目后再run'的时候发现报错com.android.support:appcompat-v7依赖报错 查看下build.gredle所配置的参数: 打开项目的build.gradl ...
- 关于多线程情况下Net-SNMP v3 版本导致进程假死情况的跟踪与分析
1.问题描述 在使用net-snmp对交换机进行扫描的时候经常会出现进程假死的情况(就是进程并没有死掉,但是看不到它与外界进行任何的数据交互).这时候不知道进程内部发生了什么,虽然有日志信息,但进程已 ...
- SoDiaoEditor电子病历编辑器更新至V3版本,愿与各位一路同行!
简单闲聊两句-- 记得刚参加工作那会儿,去医院实施,信息科不远处就是手术室,门口每天都挤满了人,他们中大多数都是等待手术结果的患者家属,有的还会把折叠床带来,应该是陪床有段时间了.有时路过,还会听到一 ...
- ComponetOne 2014 v3版本正式发布
2014年11月18日---ComponentOne Studio Enterprise 2014 v3版全球正式发布.ComponentOne Studio Enterprise是世界知名的Micr ...
- 极光API推送 (v3 版本)
Push API v3 这是 Push API 最近的版本. 相比于 API v2 版本,v3 版本的改进为: 完全基于 https,不再提供 http 访问: 使用 HTTP Basic Authe ...
随机推荐
- 牛客网-SQL专项练习2
①从学生信息表(student)中提取姓名(name)列值为NULL的记录,SQL语句为: 解析:注意不是只查name值,而是查name值为空的所有信息 SQL语句为: SELECT * FROM s ...
- HarmonyOS NEXT应用开发—城市选择案例
介绍 本示例介绍城市选择场景的使用:通过AlphabetIndexer实现首字母快速定位城市的索引条导航. 效果图预览 使用说明 分两个功能 在搜索框中可以根据城市拼音模糊搜索出相近的城市,例如输入& ...
- 涨姿势 | 一文读懂备受大厂青睐的ClickHouse高性能列存核心原理
简介: 本文尝试解读ClickHouse存储层的设计与实现,剖析它的性能奥妙 作者:和君 引言 ClickHouse是近年来备受关注的开源列式数据库,主要用于数据分析(OLAP)领域.目前国内各个大厂 ...
- 可观测告警运维系统调研——SLS告警与多款方案对比
简介: 本文介绍对比多款告警监控运维平台方案,覆盖阿里云SLS.Azure.AWS.自建系统(ELK.Prometheus.TICK)等方案. 前言 本篇是SLS新版告警系列宣传与培训的第三篇,后续我 ...
- MySQL深潜|剖析Performance Schema内存管理
简介: 本文主要是通过对PFS引擎的内存管理源码的阅读,解读PFS内存分配及释放原理,深入剖析其中存在的一些问题,以及一些改进思路. 一 引言 MySQL Performance schema(PF ...
- 2019-11-29-C#-如何写-DEBUG-输出
title author date CreateTime categories C# 如何写 DEBUG 输出 lindexi 2019-11-29 08:28:35 +0800 2018-2-13 ...
- vscode 配置c/c++环境,无法生成 *.exe文件
[问题]: 使用vscode配置c/c++环境时,提示无法构建失败. [解决方案]: 1. 当前结合网上找的资料已经检查过,tasks.json和launch.json文件,并无配置错误. 2. ...
- async 与 promise 的区别
async函数会引式返回一个promise,而promise的resolve值就是函数return的值 使用async和await明显节约了不少代码,不需要.then,不需要写匿名函数处理promis ...
- 什么是SQL 语句中相关子查询与非相关子查询
1.什么是SQL子查询 要理解相关子查询和非相关子查询,我们得首先理解什么是子查询,子查询是指在一个查询语句中嵌套的另一个查询语句. 子查询可以嵌套在其他查询语句中,如 SELECT.INSERT.U ...
- 函数编程:强大的 Stream API
函数编程:强大的 Stream API 每博一文案 只要有人的地方,世界就不会是冰冷的,我们可以平凡,但绝对不可以平庸. ------ <平凡的世界> 人活着,就得随时准备经受磨难.他已经 ...