有没有更好的方法在 Pyramid 中在 HTML 和 JSON 输出之间切换?
# /test{.format} no longer seems to work...
config.add_route('test', '/test.{ext}', view='ms.views.test')
views.py:
from pyramid.response import Response
from pyramid.renderers import render
import json
def test(request):
extension = request.matchdict['ext']
variables = {'name' : 'blah', 'asd' : 'sdf'}
if extension == 'html':
output = render('mypackage:templates/blah.pt', variables, request=request)
if extension == 'json':
output = json.dumps(variables)
return Response(output)
有没有更简单的方法来做到这一点?对于 Pylons,这很简单:
def test(self, format='html'):
c.variables = {'a' : '1', 'b' : '2'}
if format == 'json':
return json.dumps(c.variables)
return render('/templates/blah.html')
我怀疑我以错误的方式处理这个问题......?
# /test{.format} no longer seems to work...
config.add_route('test', '/test.{ext}', view='ms.views.test')
views.py:
from pyramid.response import Response
from pyramid.renderers import render
import json
def test(request):
extension = request.matchdict['ext']
variables = {'name' : 'blah', 'asd' : 'sdf'}
if extension == 'html':
output = render('mypackage:templates/blah.pt', variables, request=request)
if extension == 'json':
output = json.dumps(variables)
return Response(output)
Is there an easier way to do this? With Pylons, it was a simple:
def test(self, format='html'):
c.variables = {'a' : '1', 'b' : '2'}
if format == 'json':
return json.dumps(c.variables)
return render('/templates/blah.html')
I suspect I'm approaching this the wrong way...?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为,更好的方法是使用不同的渲染器添加相同的视图两次。假设我们有以下视图:
现在在我们的配置中,我们可以添加相同的视图两次:
我们现在拥有的:
my_view
将渲染模板"templates/my_template.mako"
如果我们将浏览器指向 url/test
,则返回的字典将作为上下文提供。my_view
发出 XHR 请求,将再次调用,但现在返回的 dict 将被编码为 JSON 并传输回调用者(请 阅读有关检查请求是否通过 XHR 完成的文档)。我们可以使用相同的想法来定义不同的路由,但附加相同的视图:
现在
/test
将触发模板渲染,但/test.json
将仅返回 JSON编码的字符串。您可以进一步通过
add_router
方法的accept
参数分派到正确的渲染器:如果请求带有标头
Accept
设置为application/json
值 JSON 将被返回,否则你会得到渲染的模板。请注意,只有当您预定义了一组数据格式并希望对视图中的响应进行编码时,这才有效,但这是常见情况。如果您需要动态调度,您可以使用
add_route
的decorate
参数来装饰您的视图,它将根据您的规则选择正确的渲染器。I think, the better way is to add the same view twice with difference renderers. Suppose we have the following view:
Now in our configuration we can add the same view twice:
What we have now:
my_view
will render template"templates/my_template.mako"
with returned dict provided as context if we will point our browser to url/test
.my_view
will be called again, but now returned dict will be encoded as JSON and transmitted back to caller (please read docs about checking if request was done via XHR).The same idea we can use for defining different routes but with the same view attached to them:
Now
/test
will trigger template rendering, but/test.json
will return just JSON encoded string.You can go further and make dispatching to the right renderer via
accept
argument ofadd_router
method:If request comes with header
Accept
set toapplication/json
value JSON will be returned, otherwise you got rendered template.Note, this will work only if you have predefined set of data formats in which you want to encode responses from your views, but it's the usual case. In case you need dynamical dispatching you can decorate your views with
decorate
argument ofadd_route
which will choose the right renderer with your rules.这是您要找的吗? Pylons 和 Pyramid 有不同的 API。所以他们会有所不同。你可以让它们变得更加相似,但你不能让它们完全相同。
Is this what you're looking for? Pylons and Pyramid have different API's. So they will be different. You can make them a little more similar, but you can't make them identical.
金字塔的URL Dispatch 是非常强大和灵活的机制。首先,我们将编写正确的 url 模式。在路由模式语法中,我们可以使用正则表达式作为替换标记。
在这里我们可以看到 url 路径应该包含 . (句号),然后是任何符号。所有符号包括 . (句号)将位于
request.matchdict
中的键ext
下。当然,我们可以使正则表达式复杂化,以指定可能存在的扩展名:
然后我们用我们的模式添加路线:
要补充的是,我们可以使用 自定义谓词。
为了指定默认扩展,我们可以使用简单的 预生成器。
之后我们将遍历来帮助我们在html 和 json 输出:
通过
add_route
中的traverse
参数,我们强制我们的应用程序成为混合。我们应该明白,为我们的视图提供上下文的工厂不得包含与我们的扩展匹配的键。 默认根工厂没有。视图.py:
在这里,我们创建了
class Test
并为其指定了路由名称。然后我们通过扩展名来分隔方法。Pyramid's URL Dispatch is very powerful and flexible mechanism. First of all, we'll write correct url pattern. In route pattern syntax we can use regular expressions for replacement markers.
Here we can see that url path should contain . (period) and then any symbols. All symbols including . (period) will be under the key
ext
inrequest.matchdict
.Of course, we can complicate the regular expression in order to specify what extensions there may be:
Then we adding route with our pattern:
Want to add, that we can specify the set of extensions using custom predicates.
In order to specify the default extension we can use simple pregenerator.
After that we'll Traversal to help us switch between html and json output:
With the
traverse
argument inadd_route
we force our application to be hybrid. And we should understand that the factory which will provide context for our views must not contain the keys matching our extensions. The default root factory doesn't.views.py:
Here we've created
class Test
and specify route name for it. And then we've separated methods by names of our extensions.尝试这种方式:
这是与您的塔示例最相似的。它还展示了一些更友好的方式来呈现模板或一些 JSON 到响应。
Try this way:
This is the most similar to your pylons example. Also it shows some more friendly way to render a template or some JSON to a response.