是否可以将 FastAPI 与 Django 一起使用?

Posted

技术标签:

【中文标题】是否可以将 FastAPI 与 Django 一起使用?【英文标题】:Is it possible to use FastAPI with Django? 【发布时间】:2020-12-22 20:14:03 【问题描述】:

我是一名 Django 开发人员,最近偶然发现了 FastAPI 框架。

然后我决定试一试。但通常当您谈论使用 Django 构建 RESTful API 时,您通常会使用 Django Rest Framework (DRF)。

是否有人知道是否可以使用 Django 特权(例如其 ORM)将 DRF 替换为 FastAPI,并且仍然可以访问 FastAPI 的所有 async 功能?

到目前为止,我只找到了一篇关于此的文章。但是在集成的过程中作者丢失了 FastAPI 的大部分特性。 You can find it here.

在 FastAPI 文档中,他们确实提到可以将某些请求重定向到 WSGI 应用程序here。

【问题讨论】:

您希望在 Django(或 DRF)中拥有什么 FastAPI 功能? django-ninja.rest-framework.com 是 DRF 的替代品,它建立在 FastAPI 之上。 @Sumithran 根据 [github.com/vitalik/django-ninja/blob/master/… Django ninja 不需要 FastAPI 及其文档状态This project was heavily inspired by FastAPI。所以它是一个并行开发,不是建立在 FastAPI 之上的 是的,例如:stavros.io/posts/fastapi-with-django 我不明白是谁决定关闭这样的问题。有时,SO“版主”的专横行为令人愤慨。这是一个完全有效且有用的问题。 【参考方案1】:

感谢您的精彩回答。这是一个稍微调整的答案,我已经修复了一些导入以及我使用了来自 Django 应用程序的模型。

from fastapi import FastAPI
from fastapi.middleware.wsgi import WSGIMiddleware
from django.core.wsgi import get_wsgi_application
import os
from importlib.util import find_spec
from fastapi.staticfiles import StaticFiles
from django.conf import settings


# Export Django settings env variable
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')

# Get Django WSGI app
django_app = get_wsgi_application()

# Import a model
# And always import your models after you export settings
# and you get Django WSGI app
from accounts.models import Account

# Create FasatAPI instance
app = FastAPI()

# Serve Django static files
app.mount('/static',
    StaticFiles(
         directory=os.path.normpath(
              os.path.join(find_spec('django.contrib.admin').origin, '..', 'static')
         )
   ),
   name='static',
)

# Define a FastAPI route
@app.get('/fastapi-test')
def read_main():
    return 
        'total_accounts': Account.objects.count(),
        'is_debug': settings.DEBUG 
    

# Mount Django app
app.mount('/django-test', WSGIMiddleware(django_app))

提示:我在我的 Django 项目的根目录中创建了一个名为 app.py 的文件,它工作正常。这是我的目录结构:

.
├── accounts
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── app.py
├── db.sqlite3
├── project
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

然后运行您的 FastAPI 应用:

(myvenv) ➜  project uvicorn --host 0.0.0.0 --port 8000 app:app --reload
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [48366] using statreload
INFO:     Started server process [48368]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

希望这对你有用。现在访问/django-test 将为您的Django 项目提供服务,而/fastapi-test 将为FastAPI 部分提供服务。

这个配置也服务于 Django 静态文件,我们也可以在 FastAPI 代码中使用我们的 Django 模型。我会进一步测试它,如果我发现任何改进的可能性,我会更新这个答案。

【讨论】:

【参考方案2】:

简答

是的,可能使用 WSGIMiddleware

例如,您可以使用所有 Django 功能 (也是管理员) 通过安装,使用此示例代码。

import os
from importlib.util import find_spec

from configurations.wsgi import get_wsgi_application
from fastapi import FastAPI
from fastapi.middleware.wsgi import WSGIMiddleware
from fastapi.staticfiles import StaticFiles

from api import router

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
os.environ.setdefault("DJANGO_CONFIGURATIN", "Localdev")

application = get_wsgi_application()

app = FastAPI()
app.mount("/admin", WSGIMiddleware(application))
app.mount("/static"
    StaticFiles(
         directory=os.path.normpath(
              os.path.join(find_spec("django.contrib.admin").origin, "..", "static")
         )
   ),
   name="static",
)

这个来自WSGIMiddleware documentation,这是一个更直接的例子(这个是为 Flask 设计的,但它展示了相同的想法。)。

from fastapi import FastAPI
from fastapi.middleware.wsgi import WSGIMiddleware
from flask import Flask, escape, request

flask_app = Flask(__name__)


@flask_app.route("/")
def flask_main():
    name = request.args.get("name", "World")
    return f"Hello, escape(name) from Flask!"


app = FastAPI()


@app.get("/v2")
def read_main():
    return "message": "Hello World"


app.mount("/v1", WSGIMiddleware(flask_app))

【讨论】:

欣赏兄弟!我会尝试一下!但它看起来很整洁。那么,app.mount("/admin", WSGIMiddleware(application)) 这一行会引用我的 django 应用程序的 urls.py 上的 /admin 吗? @LeonardoGuerreiro 是的。这个repo 也可能对你有用 当我尝试访问 django 的管理页面时,它不能很好地提供静态文件。你知道是什么原因造成的吗? admin的初始页面还可以,但是当我访问内页时,例如“用户”,它无法加载静态文件:INFO: 127.0.0.1:48012 - "GET /static/admin/img/tooltag-add.svg HTTP/1.1" 404 Not Found INFO: 127.0.0.1:48004 - "GET /static/admin/img/sorting-icons.svg HTTP/1.1" 404 Not Found 我设法修复了它。事实证明,我只需要在我调用 de FastAPI 实例的函数内将app.mount("/static", StaticFiles(directory="static"), name="static") 添加到我的asgi.py 文件中,并将其引用到settings.py 上的我的STATIC_ROOT。签出here

以上是关于是否可以将 FastAPI 与 Django 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

错误:-“详细信息”:“未找到”将 Fastapi 与 Azure 函数应用一起使用

将 Psyco 与 django 一起使用是不是有意义?

24.FastAPI静态文件

将 Django 与两个 Vuejs 组件项目一起使用

是否可以在 Django 1.5.1 中将动态属性与 Q 对象一起使用?

FastAPI 中的会话