基于类的视图在aiohttp中

9

aiohttp库中,使用基于类的处理程序而不是函数的正确方法是什么?我习惯在Django中编写处理程序作为类,所以我想知道如何在aiohttp中正确地实现。

3个回答

8

我想你希望使用基于类的处理程序来应用继承以重用代码。

从技术上讲,aiohttp web处理程序是任何接受请求参数并返回响应实例的协程。

例如:

class BaseView:
    def __init__(self, ...):
        ...

    async def __call__(self, request):
        return web.Response()

app.router.add_route('GET', '/', BaseView(...))

可以作为制作Web处理程序层次结构的基类。

甚至更多。

class Handler:
    def __init__(self, db):
        self._db = db

    async def get_from_db(self, data):
        ...

    async def handle_a(self, request):
        data = yield from self.get_from_db(
            self.extract_from_request_a(request))
        return web.Response(self.format_data(data))

    async def handle_b(self, request):
        data = yield from self.get_from_db(
            self.extract_from_request_b(request))
        return web.Response(self.format_data(data))


handler = Handler(db)
app.router.add_route('GET', '/a', hadndler.handle_a)
app.router.add_route('GET', '/b', hadndler.handle_b)

2
仍然不明白如何添加帖子(请求)功能的想法。我应该实现as_view()方法以在URL中使用吗? - vwvolodya
我已经添加了一个注册实例的示例。该代码不会为每个请求重新创建BaseView - 我发现通常我们使用Handle类的方法非常好。 - Andrew Svetlov
1
更新:最近的一个版本添加了基于类的视图。请注意,这方面存在一些问题,不是所有的aio-libs都完全支持它。 - nerdwaller
使用基于类的视图方法时,如何在路由中指定变量并不清楚,例如您可以使用@routes.get('/foobar/{something}')。 - Samantha Atkins

4

你可以这样使用:

from aiohttp import web
from datetime import datetime


class TokenView(web.View):

    async def get(self):
        token = datetime.now().strftime("%Y%m%d%H%M%S")
        room = self.request.match_info.get("room", None)
        return web.json_response({"room": room, "token": token, "result": "OK"})

    async def post(self):
        room = self.request.match_info.get("room", None)
        token = datetime.now().strftime("%Y%m%d%H%M%S")
        return web.json_response({"room": room, "token": token, "result": "OK"})


if __name__ == "__main__":

    app = web.Application()
    app.router.add_view("/token/{room}", TokenView)
    print(app.router.named_resources())
    web.run_app(app)

1

aiohttp中快速演示基于类的视图的示例

from aiohttp import web

class Users(web.View):

    async def get(self):
        output = [
            {   
                'id': 1,
                'username': 'chuck_norris'
            },
        ]
        return web.json_response(output, status=200)

    async def post(self):
        data = await self.request.json()
        output = {
            'result': data
        }
        return web.json_response(output, status=201)

    async def delete(self):
        return web.json_response(status=204)


class Teams(web.View):

    async def get(self):
        output = [
            {   
                'id': 1,
                'team': 'team1'
            },
        ]
        return web.json_response(output, status=200)

    async def post(self):
        data = await self.request.json()
        output = {
            'result': data
        }
        return web.json_response(output, status=201)

    async def delete(self):
        return web.json_response(status=204)


app = web.Application()

app.router.add_view("/users", Users)
app.router.add_view("/teams", Teams)

web.run_app(app, port=8000)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接