编程语言
首页 > 编程语言> > 使用 Django 和 FastAPI 构建 Web 应用程序:两全其美

使用 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 的人,我建议先对它更熟悉一点,然后继续阅读本文。从官方文件中添加一些参考资料:

  1. 第一步 — FastAPI (tiangolo.com)。
  2. 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)

现在来了,您可能正在等待的部分。添加模型!看看我创建的文件。目前,两个文件都是空的!

 

我们将从已创建的现有表导入并指向现有表。metadataapp.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 的管理面板。

标签:FastAPI,Web,Django
来源: