Skip to content

Commit 0e492aa

Browse files
committed
Merge branch 't3' into main
# Conflicts: # Makefile # README.md # conftest.py # example/example/settings.py # fast_tmp/admin/depends.py # fast_tmp/admin/endpoint.py # fast_tmp/admin/schema/__init__.py # fast_tmp/admin/schema/amis_json.py # fast_tmp/admin/schema/crud.py # fast_tmp/admin/schema/forms/__init__.py # fast_tmp/admin/server.py # fast_tmp/admin/templates/base.html # fast_tmp/admin/templates/index.html # fast_tmp/admin/templates/login.html # fast_tmp/amis/buttons.py # fast_tmp/amis/forms/enums.py # fast_tmp/amis/forms/widgets.py # fast_tmp/amis/page.py # fast_tmp/conf/__init__.py # fast_tmp/depends/auth.py # fast_tmp/depends/cas.py # fast_tmp/jinja_extension/tags.py # fast_tmp/models.py # fast_tmp/responses.py # fast_tmp/site/__init__.py # fast_tmp/utils/crud2.py # fast_tmp/utils/crud3.py # fast_tmp/utils/password.py # fast_tmp/utils/swagger_static_file.py # fast_tmp/utils/token.py # fast_tmp/utils/tortoise_dantic/__init__.py # fastapi_cli/__init__.py # fastapi_cli/tpl/project/{{cookiecutter.project_slug}}/.env # fastapi_cli/tpl/project/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/app.py # fastapi_cli/tpl/project/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/settings.py # poetry.lock # pyproject.toml # task.md # tests/test_example/pyproject.toml # tests/test_example/test_example/models.py # tests/test_example/test_example/schemas.py # tests/test_example/test_example/site.py # tests/testmodels.py
2 parents a02ccac + 81f707c commit 0e492aa

File tree

198 files changed

+1221342
-2485
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

198 files changed

+1221342
-2485
lines changed

Makefile

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
checkfiles = fast_tmp/ tests/
1+
checkfiles = fast_tmp/ tests/ conftest.py
22
black_opts = -l 100 -t py38
33
py_warn = PYTHONDEVMODE=1
4+
test_settings = SETTINGS_MODULE=tests.settings
5+
pytest_opts = -n auto --cov=fast_tmp --tb=native -q
46

57
help:
68
@echo "fastapi-cli development makefile"
@@ -23,24 +25,18 @@ style: deps
2325
isort -src $(checkfiles)
2426
black $(black_opts) $(checkfiles)
2527

26-
check:
28+
check: deps
2729
black --check $(black_opts) $(checkfiles) || (echo "Please run 'make style' to auto-fix style issues" && false)
2830
flake8 $(checkfiles)
29-
bandit -x test -r $(checkfiles)
30-
mypy $(checkfiles)
31+
bandit -x test -r $(checkfiles) -c pyproject.toml
32+
mypy fast_tmp/
3133

3234

33-
test:
34-
pytest tests/ --cov-report=
35+
test: deps
36+
$(py_warn) FASTAPI_SETTINGS_MODULE=tests.settings TORTOISE_TEST_DB=sqlite://:memory: pytest --cov-report html $(pytest_opts)
3537

36-
cov: deps
37-
coverage run -m pytest tests/
38-
coverage report --show-missing -m --omit=tests/*,conftest.py
39-
coverage xml
40-
coverage html
38+
test_sqlite:
39+
$(py_warn) FASTAPI_SETTINGS_MODULE=tests.settings TORTOISE_TEST_DB=sqlite://:memory: pytest --cov-report= $(pytest_opts)
4140

4241
publish: check
43-
poetry publish --build
44-
45-
docs:
46-
mkdocs build
42+
poetry publish

README.md

Lines changed: 66 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,137 +1,87 @@
1-
# fast-tmp
2-
3-
[![Python package](https://github.com/Chise1/fast-tmp/actions/workflows/test.yml/badge.svg)](https://github.com/Chise1/fast-tmp/actions/workflows/test.yml)
4-
[![codecov](https://codecov.io/gh/Chise1/fast-tmp/branch/main/graph/badge.svg?token=7CZE532R0H)](https://codecov.io/gh/Chise1/fast-tmp)
5-
[![Documentation Status](https://readthedocs.org/projects/fast-tmp/badge/?version=latest)](https://fast-tmp.readthedocs.io/?badge=latest)
6-
![GitHub](https://img.shields.io/github/license/Chise1/fast-tmp)
7-
8-
# 介绍
9-
10-
fast-tmp项目受django-admin的影响,旨在实现一个基于sqlalchemy+fastapi+amis的通用后台管理平台。
11-
12-
- sqlalchemy:python最受欢迎的数据库操作工具。
13-
- fastapi:新版本python最受欢迎的web框架之一。
14-
- amis:一款利用json数据生成页面的前端低代码项目。
15-
16-
笔者前端能力比较弱,从实用主义出发,利用amis搭建后台管理的页面。这也为未来页面的功能拓展提供了无限可能。并摆脱前端开发的影响。(由于偷懒,登陆页面用的taber构建的。以后有时间了修改)
17-
更多内容查看[教程](https://fast-tmp.readthedocs.io/)
18-
## 示例
1+
[![security: bandit](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit)
192

20-
## 该项目的存在意义
21-
22-
fastapi是一款非常优秀的web框架,long2ice基于异步数据库访问库(tortoise-orm)构建了fastapi-admin项目,使用fastapi+tortoise-orm。
23-
笔者新项目需要使用到sqlalchemy,也没有找到合适的库,所以决定自己动手来实现自己需要的功能。
24-
25-
## 页面展示
3+
# fast-tmp
264

27-
![登陆](./docs/static/img/login.png)
28-
![主页](./docs/static/img/home.png)
29-
![userinfo](./docs/static/img/userinfo.png)
30-
![create](./docs/static/img/create.png)
5+
项目模板
316

32-
## 入门
7+
## 概述
8+
本项目主要是方便快速构建fastapi的后端开发环境,依赖于```cookiecutter```,并提供方便快捷的生成路由的方法。
9+
主要使用的开发包:
3310

34-
### 安装
11+
1. fastapi
12+
2. tortoise-orm
13+
3. cookiecutter
3514

36-
通过pip进行安装:
15+
整个项目在开发过程中参考了django的一些实现方式,尽量做到简洁明了。
3716

38-
```shell
39-
pip install fast-tmp
17+
## 安装fast-tmp
18+
使用pip
19+
```shell script
20+
pip3 install fast-tmp
4021
```
41-
42-
如果使用poetry,则
43-
44-
```shell
22+
使用poetry
23+
```shell script
4524
poetry add fast-tmp
4625
```
26+
## 项目指令
27+
目前包含的操作指令有两个:
28+
1. 创建项目
29+
2. 创建超级用户
4730

48-
## 快速教程
31+
支持自定义指令并创建
4932

50-
在项目启动的根目录先创建一个.env文件,主要内容如下:
51-
52-
```text
53-
DATABASE_URL=sqlite:///example.db # 数据库
54-
SECRET_KEY=rtbhwaergvqerg # user加密用的密码
55-
DEBUG=False # 是否启动debug模式,debug模式会打印所有访问数据的的操作
33+
### 创建项目
34+
```shell script
35+
fast-tmp startproject
5636
```
57-
58-
如果你有这么一个model:
59-
60-
```python
61-
# models.py
62-
from sqlalchemy import String, Boolean, Integer, DateTime, DECIMAL, Float, JSON, Text, Column
63-
from fast_tmp.models import Base
64-
65-
66-
class UserInfo(Base):
67-
__tablename__ = "userinfo"
68-
id = Column(Integer, primary_key=True)
69-
name = Column(String(128), unique=True)
70-
age = Column(Integer, default=10, )
71-
birthday = Column(DateTime)
72-
money = Column(DECIMAL(scale=3))
73-
height = Column(Float)
74-
info = Column(JSON)
75-
tag = Column(Text)
76-
is_superuser = Column(Boolean(), default=True)
77-
78-
```
79-
80-
那么,你只需要构建一个页面model:
81-
37+
输入完所需的参数之后,就可以生成一个自己的项目。
38+
### 创建超级用户
39+
创建超级用户需要使用了fast-tmp自带的models,
40+
首先,在项目.settings的TORTOISE_ORM里面配置fast-tmp的model
8241
```python
83-
# admin.py
84-
from fast_tmp.site import ModelAdmin
85-
from .models import UserInfo
86-
87-
88-
class UserInfoAdmin(ModelAdmin):
89-
model = UserInfo
90-
create_fields = [UserInfo.name, UserInfo.age, UserInfo.birthday, UserInfo.money, UserInfo.height, UserInfo.info,
91-
UserInfo.tag, UserInfo.is_superuser]
92-
update_fields = create_fields
93-
list_display = [UserInfo.id, UserInfo.name, UserInfo.age, UserInfo.birthday, UserInfo.money, UserInfo.height,
94-
UserInfo.info,
95-
UserInfo.tag, UserInfo.is_superuser]
42+
import os
43+
TORTOISE_ORM = {
44+
'connections': {
45+
'default': {
46+
'engine': 'tortoise.backends.mysql',
47+
'credentials': {
48+
'host': os.getenv("DB_HOST"),
49+
'port': os.getenv("DB_PORT"),
50+
'user': os.getenv("DB_USER"),
51+
'password': os.getenv("DB_PASSWORD"),
52+
'database': os.getenv("DB_NAME"),
53+
}
54+
},
55+
},
56+
'apps': {
57+
'fast_tmp': {
58+
'models': ['fast_tmp.models', 'aerich.models'], # 注册app.models
59+
'default_connection': 'default',
60+
}
61+
}
62+
}
9663
```
97-
98-
然后进行注册:
99-
100-
```python
101-
# main.py
102-
from fast_tmp.site import register_model_site
103-
from example.admin import UserInfoAdmin
104-
105-
register_model_site({"Example": [UserInfoAdmin]}) # example是页面上标签名,对应是一个列表。
64+
然后,只需要执行:
65+
```shell script
66+
fast-tmp createsuperuser
10667
```
68+
### 自定义指令
10769

108-
可以把admin功能单独启动或者注册到现有项目上: 注册到项目上
109-
110-
```python
111-
from fastapi import FastAPI
112-
113-
from fast_tmp.admin.server import admin
114-
from fast_tmp.site import register_model_site
115-
from example.admin import UserInfoAdmin
116-
117-
register_model_site({"Example": [UserInfoAdmin]}) # 注册页面
118-
app = FastAPI()
119-
app.mount("/admin", admin, name="admin", ) # 注册admin的app,注意暂时只能为/admin,以后会进行修改
120-
121-
if __name__ == '__main__': # 调试模式启动
122-
import uvicorn
70+
在settings里面配置```EXTRA_SCRIPT```参数,就像配置django的参数一样,把脚本的相对导入路径写到这个字段列表里面,即可通过fast-tmp进行执行。
12371

124-
uvicorn.run(app, debug=True, port=8000, lifespan="on")
125-
```
72+
可以通过```fast-tmp --help```查看当前有哪些执行指令
12673

127-
### 创建超级用户
74+
## 功能
75+
初始化项目之后,fast-tmp包里面有如下功能:
76+
1. 全局settings管理
77+
2. crud生成器
12878

129-
```shell
130-
fast-tmp createsuperuser username password
131-
```
79+
### 全局settings管理
13280

133-
### 自定义指令
134-
135-
在settings里面配置```EXTRA_SCRIPT```参数,就像配置django的参数一样,把脚本的相对导入路径写到这个字段列表里面,即可通过fast-tmp进行执行。
81+
这个主要功能就是在所有地方都是通过```fast_tmp.conf.settings```获取设置值或环境变量。
13682

137-
可以通过```fast-tmp --help```查看当前有哪些执行指令
83+
具体使用如下:
84+
```python
85+
from fast_tmp.conf import settings
86+
...
87+
```

conftest.py

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,3 @@
1-
from typing import Generator
1+
import os
22

3-
from sqlalchemy import select
4-
from sqlalchemy.engine import ChunkedIteratorResult
5-
6-
from fast_tmp.models import Base, User
7-
import tests.models
8-
import pytest
9-
from fast_tmp.db import engine, get_db_session
10-
11-
12-
@pytest.fixture(autouse=True, scope="function")
13-
def prepare_database() -> Generator[None, None, None]:
14-
Base.metadata.create_all(engine)
15-
session = next(get_db_session())
16-
res: ChunkedIteratorResult = session.execute(select(User.username).where(User.username == "root"))
17-
if len(res.fetchall()) == 0:
18-
user = User(username="root")
19-
user.set_password("root")
20-
session.add(user)
21-
session.commit()
22-
yield
23-
Base.metadata.drop_all(engine)
3+
os.environ.setdefault("FASTAPI_SETTINGS_MODULE", "tests.settings")

example/example/admin.py

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,63 @@
1+
from test_example.models import Author, Book, FieldTesting
2+
13
from fast_tmp.site import ModelAdmin
2-
from .models import UserInfo, Author, Book
34

45

5-
class UserInfoAdmin(ModelAdmin):
6-
model = UserInfo
7-
create_fields = [UserInfo.name, UserInfo.age, UserInfo.birthday, UserInfo.money, UserInfo.height, UserInfo.info,
8-
UserInfo.tag, UserInfo.is_superuser]
9-
update_fields = create_fields
10-
list_display = [UserInfo.id, UserInfo.name, UserInfo.age, UserInfo.birthday, UserInfo.money, UserInfo.height,
11-
UserInfo.info,
12-
UserInfo.tag, UserInfo.is_superuser]
6+
class FieldTestingModel(ModelAdmin):
7+
model = FieldTesting
8+
list_display = (
9+
"name",
10+
"age",
11+
"name_inline",
12+
"age_inline",
13+
"married",
14+
"married_inline",
15+
"degree",
16+
"degree_inline",
17+
"created_time",
18+
"birthday",
19+
"config",
20+
"max_time_length",
21+
)
22+
inline = (
23+
"name_inline",
24+
"age_inline",
25+
"married",
26+
"married_inline",
27+
"degree_inline",
28+
"birthday",
29+
"config",
30+
"max_time_length",
31+
)
32+
create_fields = (
33+
"name",
34+
"age",
35+
"desc",
36+
"married",
37+
"degree",
38+
"degree_inline",
39+
"gender",
40+
"created_time",
41+
"birthday",
42+
"config",
43+
"max_time_length",
44+
)
1345

1446

15-
class AuthorAdmin(ModelAdmin):
16-
model = Author
17-
create_fields = [Author.name, Author.books]
18-
list_display = create_fields
47+
from fast_tmp.site.filter import ContainsFilter
1948

2049

21-
class BookAdmin(ModelAdmin):
50+
class BookModel(ModelAdmin):
2251
model = Book
23-
create_fields = [Book.name, Book.author] # todo 增加提醒,可以为关系,可以为id
24-
list_display = [Book.id, Book.name, Book.author] # todo 增加检查,必须在listplay里面带主键
25-
update_fields = create_fields
52+
list_display = ("name", "author", "rating")
53+
create_fields = ("name", "author", "rating")
54+
update_fields = ("name", "author")
55+
filters = (ContainsFilter("name"),)
56+
57+
58+
class AuthorModel(ModelAdmin):
59+
model = Author
60+
list_display = ("name",)
61+
create_fields = ("name",)
62+
inline = ("name",)
63+
update_fields = ("name",)

example/example/settings.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import os
2+
from typing import List
3+
24
import dotenv
35

46
dotenv.load_dotenv()
@@ -7,10 +9,26 @@
79
# from sentry_sdk.integrations.redis import RedisIntegration
810

911
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
12+
SECRET_KEY = "awdfawfqergqreef"
1013

11-
DEBUG = os.getenv("DEBUG") == "True"
12-
13-
EXTRA_SCRIPT = [] # 自定义执行脚本
14+
TORTOISE_ORM = {
15+
"connections": {
16+
"default": "sqlite://test_example.sqlite3",
17+
},
18+
"apps": {
19+
"fast_tmp": {
20+
"models": [
21+
"test_example.models",
22+
"fast_tmp.models",
23+
# "aerich.models",
24+
], # 注册app.models
25+
"default_connection": "default",
26+
}
27+
},
28+
}
29+
STATIC_ROOT = "static"
30+
STATIC_PATH = "static"
31+
EXTRA_SCRIPT: List[str] = [] # 自定义执行脚本
1432
# redis配置
1533
# REDIS_HOST = os.getenv("REDIS_HOST", "127.0.0.1")
1634
# REDIS_PORT = os.getenv("REDIS_PORT", 6379)

0 commit comments

Comments
 (0)