基于 class 的视图#
在设计API时,常见的模式是在同一个端点上根据 HTTP 方法提供多种功能。
@app.get("/foo")
async def foo_get(request):
...
@app.post("/foo")
async def foo_post(request):
...
@app.put("/foo")
async def foo_put(request):
...
@app.route("/bar", methods=["GET", "POST", "PATCH"])
async def bar(request):
if request.method == "GET":
...
elif request.method == "POST":
...
elif request.method == "PATCH":
...
虽然这两个选项都可以工作,但它们不是良好的设计实践,并且随着项目的扩展,可能难以维护。
更好的方案是:基于类的视图只是实现了对请求的响应行为的类。它们提供了一种在同一端点上处理不同 HTTP 请求类型的方法。
from sanic.views import HTTPMethodView
class FooBar(HTTPMethodView):
async def get(self, request):
...
async def post(self, request):
...
async def put(self, request):
...
app.add_route(FooBar.as_view(), "/foobar")
定义视图#
基于类的视图应该继承自 sanic.views.HTTPMethodView
。然后,你可以实现具有相应 HTTP 方法名称的类方法。如果收到没有定义方法的请求,将生成 405:不允许的方法响应。
要在端点上注册基于类的视图,可以使用 app.add_route
方法。第一个参数应该是调用了 as_view
方法的已定义类,第二个参数应该是 URL 端点。
from sanic.views import HTTPMethodView
from sanic.response import text
class SimpleView(HTTPMethodView):
def get(self, request):
return text("I am get method")
# You can also use async syntax
async def post(self, request):
return text("I am post method")
def put(self, request):
return text("I am put method")
def patch(self, request):
return text("I am patch method")
def delete(self, request):
return text("I am delete method")
app.add_route(SimpleView.as_view(), "/")
可用方法有:get
,post
,put
,patch
,delete
,head
和 options
。
定义路径参数#
class NameView(HTTPMethodView):
def get(self, request, name):
return text("Hello {}".format(name))
app.add_route(NameView.as_view(), "/<name>")
生成 URL#
这就像生成任何其他 URL 一样,只是类名是端点的一部分。
@app.route("/")
def index(request):
url = app.url_for("SpecialClassView")
return redirect(url)
class SpecialClassView(HTTPMethodView):
def get(self, request):
return text("Hello from the Special Class View!")
app.add_route(SpecialClassView.as_view(), "/special_class_view")