使用Django和FastAPI构建Web应用程序
作者:互联网
在python生态系统中,有多个框架可用于制作强大的后端。Django和FastAPI是最受欢迎的。Django具有许多开箱即用的功能,如ORM、中间件、身份验证、管理面板等。另一方面,FastAPI具有异步就绪支持,是一个超快速、轻量级的框架,用于生成Rest API。
本文的目的是探索如何在生产中利用这两个框架的力量。我们将首先设置一个简单的Django应用程序,然后逐步集成FastAPI。
注意:本文假设您熟悉框架和SQLAlchemy,并在过去的项目中使用过它们。
Django部分
我假设你那边已经准备好了基础django项目,如果没有,请在继续之前准备好。以下是使用Django的第一步的教程:设置Django项目——真正的Python。
首先,我将启动基本的图书应用程序
django-admin startapp 书
将图书应用程序添加到已安装的应用程序中
添加模型作者和书籍
从django.db导入模型 类作者(models.Model): name = models.CharField(最大长度=200) 班级书(模型。模型): title = models.CharField(最大长度=200) author = models.ForeignKey(Author,on_delete=models.CASCADE) published_date = models.DateField()
对数据库进行迁移和迁移更改。
python manage.py makemigrations && python manage.py migrate
您可能可以看到在数据库中添加两个前缀为app_name
的新表。
确保这两个表已配置。现在,我们将在管理面板中注册这些模型,并添加一些我最喜欢的书籍及其作者。
图书样本的屏幕截图:
作者:
最后,我们完成了Django的设置。推进FastAPI设置
FastAPI设置
与Django不同,FastAPI的设置需要一些工作。对于不熟悉FastAPI的人,我建议先对它更舒服一点,然后继续这篇文章。从官方文件中添加一些参考资料:
- 第一步——FastAPI(tiangolo.com)。
- GitHub — tiangolo/full-stack-fastapi-postgresql:全栈,现代Web应用程序生成器。使用FastAPI、PostgreSQL作为数据库、Docker、自动HTTPS等。
(我为FastAPI使用这个项目生成)。
确保您已准备好使用Alembic的FastAPI和Sqlalchemy的基础设置。
这是我的项目看起来是这样的。我将在最后添加回购协议的链接。
让我们从数据库(命名为db)部分开始。我们将创建基本模型,并将数据库引擎与会话绑定。
这些文件通常需要从db连接开始。你可以从我在底部添加的回购协议中获取这个。
session.py
从sqlalchemy导入create_engine 来自sqlalchemy.orm import sessionmaker 从app.core.config导入设置 engine = create_engine(settings.SQLALCHEMY_DATABASE_URI,pool_pre_ping=True) SessionLocal = sessionmaker(autocommit=False,autoflush=False,bind=engine)
这是初始化会话配置的通常设置,我们将启动sqlalchemy的元数据obj。元数据类包含给定连接中存在的所有表的信息。
从sqlalchemy导入create_engine,元数据 来自sqlalchemy.orm import sessionmaker 从app.core.config导入设置 engine = create_engine(settings.SQLALCHEMY_DATABASE_URI,pool_pre_ping=True) SessionLocal = sessionmaker(autocommit=False,autoflush=False,bind=engine) 元数据=元数据(绑定=引擎)
现在来了,你可能正在等待的部分。添加模型!看看我创建的文件。目前,这两个文件都是空的!
我们将从app.db.session
导入metadata
并指向我们已经创建的现有表。
书籍.py
从app.db.session导入元数据,引擎 来自sqlalchemy导入表 book_table = Table('<table_name>',metadata,autoload_with=engine)
在我们的示例中,将<table_name>替换为您在数据库中的确切名称,我将使用book_book作为书表,book_author用于作者表。
现在,完全分配模型的部分就是在其配置中添加一个表。
从app.db.session导入元数据,引擎 从app.db.base导入基础 来自sqlalchemy导入表 book_table = Table('book_book',metadata,autoload_with=engine) 班级书(基础): __table__ = book_table
作者.py
从app.db.session导入元数据,引擎 从app.db.base导入基础 来自sqlalchemy导入表 author_table = Table('book_author',metadata,autoload_with=engine) 类作者(基础): __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"}, ) 使用context.begin_transaction(): context.run_migrations() def run_migrations_online() -> 无: 在'在线'模式下运行迁移。 在这种情况下,我们需要创建一个引擎 并将连接与上下文相关联。 """ 可连接 = engine_from_config( config.get_section(config.config_ini_section,{}), prefix="sqlalchemy.", poolclass=pool.NullPool, ) 使用connectable.connect()作为连接: context.configure( 连接=连接,target_metadata=target_metadata ) 使用context.begin_transaction(): context.run_migrations()
在alembic的情况下,这是运行和进行迁移的2种方法。您必须将上述代码更改为以下给定的代码。
def include_object(object,名称,type_,反射,compare_to): 如果type_ ==“表”和反映和比较_to为无: 返回False 其他: 返回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"}, ) 使用context.begin_transaction(): context.run_migrations() def run_migrations_online() -> 无: 在'在线'模式下运行迁移。 在这种情况下,我们需要创建一个引擎 并将连接与上下文相关联。 """ 可连接 = engine_from_config( config.get_section(config.config_ini_section,{}), prefix="sqlalchemy.", poolclass=pool.NullPool, ) 使用connectable.connect()作为连接: context.configure( 连接=连接,target_metadata=target_metadata,include_object=include_object, ) 使用context.begin_transaction(): context.run_migrations()
顾名思义,include_object函数比较了要为迁移选择的表、序列和关系。
我们正在避免反映的模型,即从已初始化的表中提取的模型。
就是这样,现在你已经准备好运行你的API了。
uvicorn app.main:app --reload
在打开的api文档上尝试api。你会得到类似的结果。