Lyte(light)异步视图集。

LAViewSet的Python项目详细描述


LAViewSet

一个Lyte(light)异步视图集。

一个ViewSets包,A-ladjango Rest Framework-ViewSets,构建在 aiohttp.web。在

*********************************************************在

入门


快速启动
# laviewset_intro.py

from aiohttp import web
from laviewset import Route, ViewSet, HttpMethods

app = web.Application()
base_route = Route.create_base(app.router)      # '/'


class ListingsViewSet(ViewSet):

    route = base_route.extend('listings')  # '/listings'

    @route('/', HttpMethods.GET)
    async def list(self, request):
        assert isinstance(request, web.Request)
        return web.Response(text='GET at '/listings')


web.run_app(app)

如需逐步演练,请继续阅读以下内容。在

或者,skip ahead表示 更详细地看一下完全扩展laviewset.ViewSet。在


简介

第一步是通过传递 当前应用于Route.create_base

^{pr2}$

然后,base_route可以扩展为要包含在视图集中的资源:

listings_route = base_route.extend('listings')  # '/listings'
events_route = base_route.extend('/events')     # '/events'

# We can further extend a resource
sessions_route = listings.extend('sessions')    # '/listings/sessions'

既然我们有了我们想要视图集管理的资源,我们就可以创建视图集了。这就完成了 通过子类化laviewset.ViewSet,将路由包含为route属性,并重写 ViewSet方法和/或包括自定义视图:

# laviewset_intro.py

from aiohttp import web
from laviewset import Route, ViewSet, HttpMethods

app = web.Application()
base_route = Route.create_base(app.router)      # '/'


class ListingsViewSet(ViewSet):

    route = base_route.extend('listings')  # '/listings'
    serializer = 'some_serializer'

    @route('/', HttpMethods.GET)
    async def list(self, request):
        ...
        return web.Response(text='GET at /listings with {self.serializer}')


web.run_app(app)

注意,上述代码与以下代码类似:

from aiohttp import web


serializer = 'some_serializer'

def handler(request):
    ...
    return web.Response(text='GET at /listings with {self.serializer}')


app = web.Application()
app.add_routes([web.get('/', handler)])
web.run_app(app)

视图集方法

@路线装饰器

为了在视图集上创建视图,需要使用@route修饰符。因为每一个观点 本质上是^{}的包装, 传入装饰器的参数 与web.route的参数相关:第一个参数是path, 第二个参数是视图(method)的HTTP方法, 传递给decorator的任何其他关键字参数都将作为kwargsto包含 web.route方法,最后,视图本身将是handler。在

    @route('/', HttpMethods.GET, z=20, f='abc')     # z=20 and f='abc' will be
    async def list(self, request):                  # passed into web.route
        ...
        return web.Response(text='GET at '/listings')

由于laviewset背后的思想是异步视图集a-la Django Rest Framework - ViewSets, 方法listcreateretrieveupdatepartial_update,和{} 基类laviewset.ViewSet。但是,与Rest框架不同,它们并不完整:用户仍然需要 使用@route修饰符声明视图。这个设计决策的一个原因是允许 用户,例如,决定传入kwargs的内容。尝试访问上述任何方法 不重写并完成它们将返回404NotFound。在

查看方法签名

意见的签名很重要。每个视图签名至少需要selfrequest参数。 request实际上是一个web.Request对象,可以这样访问:request.queryrequest.rel_url,等等 都是无障碍的。如果在@route修饰符中声明的pathvariable path,那么{}应该 作为KEYWORD_ONLY参数包含在视图签名中,并且与 路径中包含标识符,否则将引发laviewset.ViewSignatureError

# Correct

    @route(r'/{pk:\d+}', HttpMethods.GET)  # /listings/123
    async def retrieve(self, request, *, pk):   # `pk` is KEYWORD_ONLY and
        assert pk == 123                        # `pk` is same as identifier
        return web.Response(text=f'retrieved {pk}')

# Incorrect

    @route(r'/{pk:\d+}', HttpMethods.GET)
    async def retrieve(self, request, pk):      # `pk` is not KEYWORD_ONLY
        ...
        return web.Response(text=f'retrieved {pk}')

# Incorrect

    @route(r'/{fk:\d+}', HttpMethods.GET)
    async def retrieve(self, request, *, pk):  # `pk` != `fk`
        ...
        return web.Response(text=f'retrieved {pk}')


自定义视图

也可以定义自定义视图。只需用@route修饰符包装方法 并遵循上述规则:

    # Custom GET view
    # '/listings/123/events/Coachella'
    @route(r'/{pk:\d+}/events/{name:\w+}', HttpMethods.GET)
    async def custom_get(self, request, *, pk, name):
        assert pk == 123
        assert name == 'Coachella'
        return web.Response(text=f'GET at /listings/{pk}/events/{name}')

    # Custom DELETE view
    # '/listings/custom_delete/123/Coachella'
    @route(r'/custom_delete/{pk:\d+}/{name:\w+}', HttpMethods.DELETE)
    async def custom_delete(self, request, *, pk, name):
        assert pk == 123
        assert name == 'Coachella'
        return web.Response(text=f'Deleting something to do with {pk} {name}')

A short note on errors:
All laviewset errors are raised "statically", i.e. before your server is up and running.


项目结构

由于视图集不需要初始化,所以让应用程序的模块成为 了解每一个ViewSet。因此,对于更复杂的项目结构,以下内容 建议结构:

proj/
├── package/
│   ├── __init__.py
│   ├── __main__.py
│   ├── server.py
│   ├── app1/
│   │   └── views.py
│   └── app2/
│       └── views.py
├── conf.py
└── README.md
# package/server.py

from aiohttp import web
from laviewset import Route

app = web.Application()
base_route = Route.create_base(app.router)


def run_server(app: web.Application) -> None:
    web.run_app(app, host='localhost', port=8000)

# package/app1/views.py

from laviewset import ViewSet
from ..server import base_route
...
# package/app2/views.py

from laviewset import ViewSet
from ..server import base_route
...
# package/__init__.py

# Now `server.app` knows about `ViewSet`s.
from .app1 import views
from .app2 import views
# package/__main__.py

from .server import app, run_server

run_server(app)

*********************************************************在

Cheatsheet

# quicksetup.py

from aiohttp import web
from laviewset import Route, ViewSet, HttpMethods

app = web.Application()
base_route = Route.create_base(app.router)


class ListingsViewSet(ViewSet):

    route = base_route.extend('listings')  # '/listings'

    @route('/', HttpMethods.GET)
    async def list(self, request):
        # GET at '/listings'
        ...
        return web.Response(...)

    @route(r'/{pk:\d+}', HttpMethods.GET)
    async def retrieve(self, request, *, pk):
        # GET at '/listings/{pk}'
        # where the dynamic value {pk} can be accessed 
        # through `pk`.
        ...
        return web.Response(...)

    @route('/', HttpMethods.POST)
    async def create(self, request):
        # POST at '/listings'
        data = await request.json()
        return web.Response(text=f'Metrics Created data: {data}')

    @route(r'/{pk:\d+}', HttpMethods.DELETE)
    async def delete(self, request, *, pk):
        # DELETE at '/listings/{pk}'
        ...
        return web.Response(...)

    @route(r'/{pk:\d+}', HttpMethods.PUT)
    async def update(self, request, *, pk):
        # PUT at '/listings/{pk}'
        ...
        return web.Response(...)

    @route(r'/{pk:\d+}', HttpMethods.PATCH)
    async def partial_update(self, request, *, pk):
        # PATCH at '/listings/{pk}'
        ...
        return web.Response(...)

    @route(r'/{pk:\d+}/do_thing/{name:\w+}', HttpMethods.GET)
    async def custom_view(self, request, *, pk, name):
        # GET at '/listings/{pk}/do_thing/{name}'
        ...
        return web.Response(...)

*********************************************************在

要求

  • Python>;=3.8
  • aiohttp==3.6.2

*********************************************************在

安装

这个包在PyPI上还不存在,所以 通过LAViewSet/setup.py安装。在

*********************************************************在

许可证

laviewset是根据麻省理工学院的许可证提供的。在

这个包使用^{}包,它是在Apache2许可证下分发的。在

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
实现接口方法时不允许java@Override   使用BuffereImage加载映像时java高ram使用率   java For循环混乱,为什么不是循环?   java Android网格视图字符串对齐问题   java如何将方法与比较类型的附加功能进行比较?   在Java Swing中放置JSepator后的间隙大小   java如何避免并发访问我的网站中的支付链接   java如何从现有的Unix服务器连接到FTP服务器?   Spring中的java用户相关bean定义   带有scribesjava库的wordpress Woocommerce REST API返回消费者密钥参数缺失错误消息   java我可以自动检测特定设备连接的串行端口吗?   Javafx棋盘游戏   java使用JTextPane显示HTML,支持SVG吗?   SpringBoot如何在java中将映射转换为实体对象?   如何使用java代码对xls文件进行密码保护   Java JPA(EclipseLink)如何在持久化实际实体之前接收下一个生成的值?   Javaservlet启动外部进程