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
:
然后,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的任何其他关键字参数都将作为kwargs
to包含
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,
方法list
,create
,retrieve
,update
,partial_update
,和{laviewset.ViewSet
。但是,与Rest框架不同,它们并不完整:用户仍然需要
使用@route
修饰符声明视图。这个设计决策的一个原因是允许
用户,例如,决定传入kwargs
的内容。尝试访问上述任何方法
不重写并完成它们将返回404NotFound
。在
查看方法签名
意见的签名很重要。每个视图签名至少需要self
和request
参数。
request
实际上是一个web.Request
对象,可以这样访问:request.query
,request.rel_url
,等等
都是无障碍的。如果在@route
修饰符中声明的path
是
variable 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:
Alllaviewset
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
是根据麻省理工学院的许可证提供的。在
这个包使用^{
- 项目
标签: