使用 Django 和 FastAPI 构建 Web 应用程序:两全其美
作者:互联网
在python生态系统中,有多个框架可用于制作健壮的后端。Django和FastAPI是最受欢迎的。Django 带有许多开箱即用的功能,如 ORM、中间件、身份验证、管理面板等。另一方面,FastAPI具有异步就绪支持,是一个超快速,轻量级的框架来生成Rest API。
本文的目的是探讨如何在生产中利用这两个框架的强大功能。我们将首先设置一个简单的Django应用程序,然后转向集成FastAPI。
注意:本文假定您熟悉框架和 SQLAlchemy,并在过去的项目中使用过它们。
姜戈部分
我将假设你已经准备好了基本的django项目,如果没有,请在继续之前准备好它。这是使用 Django 的第一步:设置 Django 项目 — Real Python。
首先,我将启动基本的书籍应用程序
django-admin startapp book
将图书应用添加到已安装的应用
添加模型作者和书籍
从 django 导入模型 类.db Author(models.型号): 名称 = 型号。查菲尔德(max_length=200) 类书(模型.型号): 标题 = 型号。CharField(max_length=200) 作者 = 模型。外键(作者,on_delete=模型。级联) published_date = 模型。日期字段()
对数据库进行迁移和迁移更改。
python manage.py makemigrations && python manage.py migrate
您可能能够看到两个新表都添加了前缀,就像在数据库中一样。app_name
确保配置了这两个表。现在,我们将在管理面板中注册这些模型,并添加一些我最喜欢的书籍及其作者。
书籍样本截图:
最后,我们完成了 Django 的设置。推进快速API设置
快速接口设置
与Django不同,FastAPI的设置需要一些工作。对于不熟悉 FastAPI 的人,我建议先对它更熟悉一点,然后继续阅读本文。从官方文件中添加一些参考资料:
- 第一步 — FastAPI (tiangolo.com)。
- GitHub — tiangolo/full-stack-fastapi-postgresql:全栈,现代Web应用程序生成器。使用FastAPI,PostgreSQL作为数据库,Docker,自动HTTPS等。
(我将此项目生成用于 FastAPI)。
确保你已经准备好了FastAPI和Sqlalchemy与Alembic的基本设置。
这是我的项目外观。我将在最后添加指向存储库的链接。
让我们从数据库(名为 db)部分开始。我们将创建基本模型并将数据库引擎与会话绑定。
这些是通常从数据库连接开始所需的文件。您可以从我在底部添加的存储库中获取它。
session.py
从 SQLLalchemy 导入create_engine 从 SQLLalchemy.orm 导入 会话制作者 从 app.core.config 导入设置引擎 = create_engine (设置 。SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
这是初始化会话配置的常用设置,我们将启动 sqlalchemy 的元数据对象。元数据类包含有关给定连接中存在的所有表的信息。
从 sqlalchemy import create_engine,元数据 从 sqlalchemy.orm 导入会话生成器 从 app.core.config 导入设置 引擎 = create_engine(settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)metadata = MetaData(bind=engine)
现在来了,您可能正在等待的部分。添加模型!看看我创建的文件。目前,两个文件都是空的!
我们将从已创建的现有表导入并指向现有表。metadata
app.db.session
books.py
from app.db.session import metadata, engine from sqlalchemy import Table book_table = Table('<table_name>',metadata,autoload_with=engine)
在我们的示例中,将<table_name>替换为数据库中的确切版本,我将对书籍表使用 book_book,对作者表使用 book_author。
现在只剩下完全分配模型的部分是在其配置中添加一个表。
from app.db.session import metadata, engine from app.db.base import Base from sqlalchemy import Table book_table = Table('book_book',metadata,autoload_with=engine) class Book(Base): __table__ = book_table
author.py
from app.db.session import metadata,engine from app.db.base import Base from sqlalchemy import Table author_table = Table('book_author',metadata,autoload_with=engine) class Author(Base): __table__ = author_table
做?不!还剩下更重要的一步。我知道这篇文章很长,但请留在我身边。
我们需要告诉alembic不要对这些模型进行任何迁移,因为Django正在管理这些实体。你也可以做相反的事情,但我认为这是一个更复杂的版本。
alembic/env.py
def run_migrations_offline() -> 无:“ ”“在'离线'模式下运行迁移。 这将仅使用 URL 而不是引擎配置上下文,尽管此处也可以接受 引擎。通过跳过引擎创建 ,我们甚至不需要可用的 DBAPI。 此处对 context.execute() 的调用将给定的字符串发送到 脚本输出中。 “”“ url = config.get_main_option(”sqlalchemy.url“) context.configure( url=url, target_metadata=target_metadata, literal_binds=True, dialect_opts={”paramstyle“: ”named“ }, ) with context.begin_transaction(): context.run_migrations() def run_migrations_online() -> 无:“ ”“”在'在线'模式下运行迁移。 在这种情况下,我们需要创建一个引擎 并将连接与上下文相关联。 “”“ connectable = engine_from_config( config.get_section(config.config_ini_section, {}), prefix=”sqlalchemy.“ , poolclass=pool.NullPool, ) 与 connectable.connect() 作为连接: context.configure( connection=connection, target_metadata=target_metadata ) 与 context.begin_transaction(): context.run_migrations()
在alembic的情况下,这是运行和进行迁移的2种方法。您必须将上面的代码更改为给定的以下代码。
def include_object(对象、名称、type_、反射、compare_to): 如果type_ == “表”并反射且compare_to为 None:返回 False else: 返回 True def run_migrations_offline() -> 无:“ ”“在'脱机'模式下运行迁移。 这将仅使用 URL 而不是引擎配置上下文,尽管此处也可以接受 引擎。通过跳过引擎创建 ,我们甚至不需要可用的 DBAPI。 此处对 context.execute() 的调用将给定的字符串发送到 脚本输出中。 “”“ url = config.get_main_option(”sqlalchemy.url“) context.configure( url=url, target_metadata=target_metadata, literal_binds=True, include_object=include_object, dialect_opts={”paramstyle“: ”named“ }, ) with context.begin_transaction(): context.run_migrations() def run_migrations_online() -> 无:“ ”“”在'联机'模式下运行迁移。 在这种情况下,我们需要创建一个引擎 并将连接与上下文相关联。 “”“ connectable = engine_from_config( config.get_section(config.config_ini_section, {}), prefix=”sqlalchemy.“ , poolclass=pool.NullPool, ) 与 connectable.connect() 作为连接: context.configure( connection=connection, target_metadata=target_metadata,include_object=include_object, ) 与 context.begin_transaction(): context.run_migrations()
顾名思义,include_object功能可比较要为迁移选择的表、序列和关系。
我们避免了反映的模型,即从已经初始化的表中获取的模型。
现在,您就可以运行 API 了。
uvicorn app.main:app --reload
在打开的 api 文档中试用 API。你会得到类似的结果。