240219_Django Ninja

本来是打算仔细学FastAPI作为主力后端框架的,后来又意外发现了Django Ninja。api的写法和FastAPI很相似。
基于Django,是一个Fast Django REST Framework,能利用Django的ORM等生态。于是决定目前重点学Django Ninja作为主力后端。
環境構築
1 | pip install django-ninja |
当然django本身作为依赖是要安装的 pip install Django
创建项目,运行项目和Django一样:
创建项目:
1 | django-admin startproject xxx |
创建一个应用:
1 | python manage.py startapp xxx |
完了后记得去settings.py
的INSTALLED_APPS下追加startapp
的app
启动后端服务器:(默认8000端口)
1 | python manage.py runserver |
更换服务器的监听端口,请使用命令行参数
1 | python manage.py runserver 8080 |
设置TIME_ZONE
1 | TIME_ZONE = 'Asia/Shanghai' |
runserver
后命令行显示的时间应该就是本地时区了
创建管理员:(可以登录管理员后台:8000/admin)
1 | python manage.py createsuperuser |
(Username: admin Password: chedishibai)
startapp
创建的app目录下编辑admin.py
追加models后,可以登录管理员后台,在界面上crud
https://docs.djangoproject.com/zh-hans/5.0/intro/overview/
https://docs.djangoproject.com/zh-hans/5.0/intro/tutorial02/#introducing-the-django-admin
在数据库中创建表
1 | python manage.py migrate |
migrate
命令只会为在INSTALLED_APPS
里声明了的应用进行数据库迁移
根据检测到的模型变化创建新的迁移(反正就是改变了models就要makemigrations)
1 | python manage.py makemigrations |
改变模型需要这三步:
- 编辑
models.py
文件,改变模型 - 运行
python manage.py makemigrations
to create migrations for those changes - 运行
python manage.py migrate
to apply those changes to the database
Django的Python shell交互
1 | python manage.py shell |
然后可以手动插入一条记录之类的
https://docs.djangoproject.com/en/5.0/intro/tutorial02/#playing-with-the-api
apiの書き方
在startproject
的project目录下(app目录下也可以)创建个api.py
文件。(对,放弃使用views.py
了,views.py
本质是返回渲染的html模板,前后端分离后这个views.py
文件也变得鸡肋了)
导入NinjaAPI类:
1 | from ninja import NinjaAPI |
项目目录的urls.py
追加:
1 | from django.contrib import admin |
注意: 后端定义api的url最后面slashを付いた方が良い
如果@recommendation_api.get("/recommend")
,前端发的请求的url最后要是有”/“,那服务端响应不了,Not Found 404
但@recommendation_api.get("/recommend/")
(最后slashを付いた),不管前端发的请求的url最后有没有slash,服务端都能响应
有了Django Ninja, 处理endpoint函数会自动做serialization,把return的python dict转成(serialize to)json. (应该是decorator做的)
(DRF djangorestframework是需要serializer操作的)
CRUD官网例子:https://django-ninja.dev/tutorial/other/crud/
1 |
|
post例子中**payload.dict()
两个星是把hash map{}给destructure成keyword arguments以便传给create()
JSON转python dict也是django-ninja框架自动实现的,定义了schema(说是Schema其实是检查request body有没有缺字段)的话,如此处的EmployeeIn
但定义Schema是必要的(什么xxxIn, xxxOut),不然报错TypeError: Object of type QuerySet is not JSON serializable
自定义错误信息,特别是request body不匹配时,ninja的Schema会自动报错
https://django-ninja.dev/guides/errors/
手撸request, response
https://docs.djangoproject.com/en/5.0/ref/request-response/
https://www.jianshu.com/p/94785f71fdd8
见我PFN的oa题
models ORM 数据库
学数据库的时候,就感觉到一张表的schema就像定义一个类,一行记录就像一个类的实例
models定义的class属性不需要写id,migrate时Django会自动产生一个id (除非指定了作为pk *primary_key*=True
)
参考Django文档 https://docs.djangoproject.com/zh-hans/5.0/intro/tutorial02/
各种字段类型 https://docs.djangoproject.com/zh-hans/5.0/ref/models/fields/#field-types
https://docs.djangoproject.com/en/5.1/topics/db/queries/
各种ORM方法 https://docs.djangoproject.com/en/5.1/ref/models/querysets/
自定义User Model
from django.contrib.auth.models import AbstractUser
https://cloud.tencent.com/developer/article/1743076
https://cloud.tencent.com/developer/article/1358567
https://stackoverflow.com/questions/21514354/abstractuser-vs-abstractbaseuser-in-django
连MariaDB/MySQL
从官网文档 How the documentation is organized -> Reference guides去找 Databases
https://docs.djangoproject.com/en/5.0/ref/databases/#mysql-notes
安装Python的MySQL客户端
https://pypi.org/project/mysqlclient/ 官方文档推荐的
mysqlclient is a native driver. It’s the recommended choice.
1 | sudo pacman -S python-mysqlclient |
MariaDB/MySQL先要创建数据库
1 | MariaDB [(none)]> create database arxiv; |
连接数据库
修改settings.py的DATABASES
1 | DATABASES = { |
然后迁移 python manage.py migrate
,MariaDB里就有表了
或者使用配置文件
1 | DATABASES = { |
根目录(和db.sqlite3同级)创建个mariadb.cnf文件
1 | [client] |
但这样直接migrate会报错,参考: https://zhuanlan.zhihu.com/p/488566846
使用PyMySQL, pip install PyMySQL
,项目目录 __init__.py
中写入:
1 | import pymysql |
然后再migrate就可以了
ORM的各种操作 objects.xxx()
从官网文档 The model layer 去看
https://docs.djangoproject.com/en/5.0/topics/db/queries/
https://docs.djangoproject.com/en/5.0/ref/models/querysets/
sqlmigrate
命令接收一个迁移的名称 polls/migrations/0001_initial.py
,然后返回对应的 SQL:
1 | python manage.py sqlmigrate polls 0001 |
查看SQL语句,确实主键(id)会被自动创建 (settings.py或apps.py中的DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
)
sqlmigrate
命令并没有真正在你的数据库中执行迁移 - 相反,它只是把命令输出到屏幕上,让你看看Django认为需要执行哪些SQL语句
插入假数据:
1 | pip install Faker |
1 | import random |
用Faker
库往数据库里插入假数据。注意不能用python generate_fake_data.py
运行会报错导入不了model。
需要在django shell里运行
1 | python manage.py shell |
然后粘贴Enter,数据库里有了
CORS
https://github.com/adamchainz/django-cors-headers
Response Header里应该有access-control-allow-origin
字段ようになった
注意 CORS_ALLOW_CREDENTIALS = True
, 不然cookie不会被发到不同源的前端
Pagination 分页
https://django-ninja.dev/guides/response/pagination/
登录注册&权限
https://docs.djangoproject.com/ja/5.0/topics/auth/default/
https://docs.djangoproject.com/zh-hans/5.0/topics/auth/customizing/
用自带的 from django.contrib.auth import authenticate, login, logout
Django自带的auth登录认证 django.contrib.auth里自带方法的使用,还有AbstractUser (注意settings.py里追加AUTH_USER_MODEL)
https://zhuanlan.zhihu.com/p/677674023 手撸版,但login仅仅只是展示username,没有涉及session,token
https://www.bilibili.com/video/BV1SW4y1F7gT?p=52&vd_source=0ae70a0cf4a652e3c632b9150cd2f90e 手撸版,很赞
https://zhuanlan.zhihu.com/p/377145935 手撸版自定义
JWT
Django API Authentication using JWT Tokens 用的是DRF(djangorestframework),==很有启发性==,包括用户模型应该继承自AbstractUser (还有postman里看cookie,才意识到问题是cookie没写到浏览器里,然后axios cookie一搜,axios跨域默认不带cookie)
Django User 模块之 AbstractUser 扩展详解 AbstractUser (注意settings.py里追加AUTH_USER_MODEL)
参考
DjangoCon 2022 | Introducing Django Ninja DjangoCon Europe上作者发表,作者是🇺🇦人。注意看对Schema类的介绍,不需要再自己做类型转换了,request body的json直接转成了python dict。Schema像是对request/response做类型检查以及过滤余計的数据 (说是Schema其实是数据库里的视图View)
CRUD with Django Ninja 来自官方油管,作者自ら解説。跟着做library项目,思路流程清晰。19min左右学到了Schema里再套Schema,比如Book表只存了author_id,但想要一起显示author的其他属性
Creating a CRUD API with Django-Ninja 这位油管主讲得也很明白
https://www.bugbytes.io/posts/django-ninja/
Django-Ninja APIs - Modern API Development in Django 涉及到Schema和django-ninja-extra库
Django Ninja Ecommerce Inventory Integration
Django Ninja CRUD | Managing Form data | Image Uploads 最后有上传文件
- Title: 240219_Django Ninja
- Author: Haoliang Tang
- Created at : 2024-02-19 00:00:00
- Updated at : 2025-04-29 23:36:33
- Link: https://hl-tang.github.io/2024/02/19/240219_Django Ninja/
- License: This work is licensed under CC BY-NC-SA 4.0.