使用 Django 和 FastAPI 构建 Web 应用程序:两全其美
作者:互联网
在python生态系统中,有多个框架可用于制作健壮的后端。Django和FastAPI是最受欢迎的。Django 带有许多开箱即用的功能,如 ORM、中间件、身份验证、管理面板等。另一方面,FastAPI具有异步就绪支持,是一个超快速,轻量级的框架来生成Rest API。
本文的目的是探讨如何在生产中利用这两个框架的强大功能。我们将首先设置一个简单的Django应用程序,然后转向集成FastAPI。
注意:本文假定您熟悉框架和 SQLAlchemy,并在过去的项目中使用过它们。
姜戈部分
我将假设你已经准备好了基本的django项目,如果没有,请在继续之前准备好它。这是使用 Django 的第一步:设置 Django 项目 — Real Python。
首先,我将启动基本的书籍应用程序
django-admin startapp book
将图书应用添加到已安装的应用
添加模型作者和书籍
from django.db import models class Author(models.Model): name = models.CharField(max_length=200) class Book(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey(Author,on_delete=models.CASCADE) published_date = models.DateField()
对数据库进行迁移和迁移更改。
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
from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from app.core.config import settings engine = create_engine(settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
这是初始化会话配置的常用设置,我们将启动 sqlalchemy 的元数据对象。元数据类包含有关给定连接中存在的所有表的信息。
from sqlalchemy import create_engine, MetaData from sqlalchemy.orm import sessionmaker from app.core.config import settings engine = 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
来自应用程序数据库。会话导入元数据,来自 sqllchemy import 的引擎 表 book_table = 表 ('<table_name>',元数据,autoload_with=引擎 )
在我们的示例中,将<table_name>替换为数据库中的确切版本,我将对书籍表使用 book_book,对作者表使用 book_author。
现在只剩下完全分配模型的部分是在其配置中添加一个表。
来自应用程序数据库。会话导入元数据,来自 app.db 的引擎 。基本导入 从 sqllchemmy 导入的基础 表 book_table = 表 ('book_book',元数据,autoload_with=引擎) 类 书(基): __table__ = book_table
author.py
来自应用程序数据库。会话导入元数据,引擎 从应用程序.db。基本导入 从 sqllcellmy 导入的基础 表 author_table = 表 ('book_author',元数据,autoload_with=引擎) 类 作者(基本): __table__ = author_table
做?不!还剩下更重要的一步。我知道这篇文章很长,但请留在我身边。
我们需要告诉alembic不要对这些模型进行任何迁移,因为Django正在管理这些实体。你也可以做相反的事情,但我认为这是一个更复杂的版本。
alembic/env.py
def run_migrations_offline() -> None: """Run migrations in 'offline' mode. This configures the context with just a URL and not an Engine, though an Engine is acceptable here as well. By skipping the Engine creation we don't even need a DBAPI to be available. Calls to context.execute() here emit the given string to the script output. """ 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() -> None: """Run migrations in 'online' mode. In this scenario we need to create an Engine and associate a connection with the context. """ connectable = engine_from_config( config.get_section(config.config_ini_section, {}), prefix="sqlalchemy.", poolclass=pool.NullPool, ) with connectable.connect() as connection: context.configure( connection=connection, target_metadata=target_metadata ) with context.begin_transaction(): context.run_migrations()
在alembic的情况下,这是运行和进行迁移的2种方法。您必须将上面的代码更改为给定的以下代码。
def include_object(object, name, type_, reflected, compare_to): if type_ == "table" and reflected and compare_to is None: return False else: return True def run_migrations_offline() -> None: """Run migrations in 'offline' mode. This configures the context with just a URL and not an Engine, though an Engine is acceptable here as well. By skipping the Engine creation we don't even need a DBAPI to be available. Calls to context.execute() here emit the given string to the script output. """ 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() -> None: """Run migrations in 'online' mode. In this scenario we need to create an Engine and associate a connection with the context. """ connectable = engine_from_config( config.get_section(config.config_ini_section, {}), prefix="sqlalchemy.", poolclass=pool.NullPool, ) with connectable.connect() as connection: context.configure( connection=connection, target_metadata=target_metadata,include_object=include_object, ) with context.begin_transaction(): context.run_migrations()
顾名思义,include_object功能可比较要为迁移选择的表、序列和关系。
我们避免了反映的模型,即从已经初始化的表中获取的模型。
现在,您就可以运行 API 了。
uvicorn app.main:app --reload
在打开的 api 文档中试用 API。你会得到类似的结果。
我们在这里完成了,现在您可以使用 FastAPI 制作快速性能的 API,同时使用 Django 的管理面板。