可以在Django上使用FastAPI吗?

mftmpeh8  于 2023-01-31  发布在  Go
关注(0)|答案(5)|浏览(233)

我是一名Django开发人员,最近偶然发现了FastAPI框架。
然后我决定给予一下,但通常当你谈论用Django构建RESTful API时,你通常会使用Django Rest框架(DRF)。
有人知道是否有可能使用Django的额外功能(比如ORM)用FastAPI代替DRF,同时仍然可以访问FastAPI的所有async特性吗?
到目前为止,我只找到了一篇关于这方面的文章。但是在集成的过程中,作者丢失了FastAPI. You can find it here的大部分特性。
在FastAPI文档中,他们确实提到可以将某些请求重定向到WSGI应用程序here

ulmd4ohb

ulmd4ohb1#

简短回答

是的,使用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))
iyr7buue

iyr7buue2#

更新

虽然下面列出的方法是可行的,但我真心认为我们应该避免将不同的框架耦合成一个整体,这样做可能会导致意想不到的bug,并使其难以扩展。
相反,我们可以在FastAPI中构建一个后端服务,例如一个Django管理服务,然后使用NGINX将流量路由到这些后端服务。使用NGINX将流量路由到不同的后端服务在生产中是很常见的。

FastAPI与Django的集成(WSGI)

https://github.com/jordaneremieff/django-fastapi-example.git
经过几个小时的搜索,我终于在上面的链接中找到了一个很棒的实现。它对我来说工作得天衣无缝!

测试

为了简化测试,下面是我对上面的引用所做的一些调整:

    • 美国石油学会/www.example.commodels.py
class Item(models.Model):
    title = models.CharField(max_length=50)
    description = models.TextField()
    # owner = models.ForeignKey(
    #     settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="items"
    # )
    • 美国石油学会/www.example.comschemas.py
class Item(ItemBase):
    # id: int
    # owner_id: int

    class Config:
        orm_mode = True
    • 邮寄**
curl -d "{\"title\":\"le titre\", \"description\":\"la description\"}" -H "Content-Type: application/json" -X POST http://127.0.0.1:8000/api/items
    • 得到**
curl http://127.0.0.1:8000/api/items
ars1skjm

ars1skjm3#

谢谢你的回答。这里是一个小调整的答案,我已经修复了一些导入,以及我已经使用了一个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模型。我会进一步测试它,如果我发现任何改进的可能性,我会更新这个答案。

dvtswwa3

dvtswwa34#

正如Sumitrhan在一篇评论中指出的:还有一个项目Django Ninja,它使用了非常相似的概念,如快速API(路径,Pydandantic模型验证),但只是一个Django应用程序。
考虑到目前的Django也支持异步视图,我认为没有必要混合Django和FastApi,以获得相同的功能集,只是复杂得多,而不是很好地集成。

hpcdzsge

hpcdzsge5#

良好的资源如下:
合并FastAPI和Django的强大功能

相关问题