为PMR2定制z3c.form和plone.z3cform库
项目描述
介绍
此软件包扩展了z3c.form和plone.z3cform,以便在PMR2和相关库中使用。此软件包试图解决的问题包括
确保在渲染表单(以及视图/页面)时采用正确的根模板,以便只有一个类用于测试和生产,无需为特定用途进行子类化或使用包装类/方法。可能可以通过将根视图注册到所需的层来支持其他框架。
通过使用适当的表单验证器(例如,Plone的plone.protect)来预防CSRF(跨站请求伪造)。
向标准非表单视图提供相同的可适应浏览器类(页面)。
带有遍历子路径的表单。
安装和使用
只需在典型的setup.py中的设置函数中添加或修改install_requires选项。示例
from setuptools import setup setup( ... install_requires=[ ... 'pmr2.z3cform', ] )
表单
PMR2中的表单是在z3c.forms之上构建的。我们对该库进行了一些修改,以便它更好地适应我们的用例。有两个修改,第一个是强制请求方法,另一个是CSRF(跨站请求伪造)保护。
首先,我们导入一些基类并创建一个测试表单类
>>> import zope.interface >>> import zope.schema >>> import z3c.form.field >>> from pmr2.z3cform.testing import BaseTestRequest as TestRequest >>> from pmr2.z3cform.tests import base >>> from pmr2.z3cform.form import AddForm >>> >>> class IDummy(zope.interface.Interface): ... id = zope.schema.DottedName(title=u'id') ... >>> class Dummy(object): ... zope.interface.implements(IDummy) ... def __init__(self, id_): ... self.id = id_ ... >>> class TestAddForm(AddForm): ... fields = z3c.form.field.Fields(IDummy) ... def create(self, data): ... return Dummy(data['id']) ... def add_data(self, ctxobject): ... ctxobject.id = self._data['id'] ... def add(self, obj): ... self.context.append(obj) ... def nextURL(self): ... return '' # unnecessary.
首先要演示的是请求方法验证。必须由简单GET请求激活操纵数据的形式
>>> context = [] >>> request = TestRequest(form={ ... 'form.widgets.id': 'test', ... 'form.buttons.add': '1', ... }) >>> request.method = 'GET' >>> form = TestAddForm(context, request) >>> result = form() Traceback (most recent call last): ... Unauthorized: Unauthorized() >>> context == [] True
另一方面,POST请求不会触发权限错误
>>> request.method = 'POST' >>> form = TestAddForm(context, request) >>> form.disableAuthenticator = True >>> result = form() >>> print context[0].id test
然而,请注意安全验证器被禁用了。这提供的是检查请求中必须包含的CSRF预防令牌。现在尝试启用检查,因为它默认是启用的
>>> context = [] >>> request.method = 'POST' >>> form = TestAddForm(context, request) >>> result = form() Traceback (most recent call last): ... Unauthorized: Unauthorized() >>> context == [] True
如果提供了令牌,作为使用本站点渲染的表单的正常表单提交过程的一部分,该令牌将被包含在一个隐藏的输入字段中。在Plone的情况下,此令牌由认证视图提供。如果我们包含生成的令牌,表单将正确提交。
>>> context = [] >>> authed_request = base.TestRequest(form=request.form) >>> authed_request.method = 'POST' >>> '_authenticator' in authed_request.form True >>> form = TestAddForm(context, authed_request) >>> result = form() >>> print context[0].id test
页面
这些只是简单的渲染页面,旨在被布局类包裹,将被更标准的Plone模板渲染方式所取代。
让我们创建一个子类
>>> from pmr2.z3cform.tests.base import TestRequest >>> from pmr2.z3cform.page import SimplePage >>> >>> class TestPage(SimplePage): ... template = lambda x: 'Hello'
然后渲染它
>>> context = self.portal >>> request = TestRequest() >>> page = TestPage(context, request) >>> print page() <h1 class="documentFirstHeading">Plone site</h1> <div id="content-core"> <div>Hello</div> </div>
如果我们在此主站上注册此视图,我们应该能够使用testbrowser渲染它。然后,它将以与Plone关联的所有模板一起渲染相同的页面
>>> import zope.component >>> from Testing.testbrowser import Browser >>> zope.component.provideAdapter(TestPage, (None, None), ... zope.publisher.interfaces.browser.IBrowserView, ... name='pmr2z3cform-testpage') ... >>> tb = Browser() >>> tb.open(context.absolute_url() + '/@@pmr2z3cform-testpage') >>> 'Plone - http://plone.org' in tb.contents True >>> '<div>Hello</div>' in tb.contents True
虽然遍历视图通常是实现特定的,但仍然可以进行快速演示。尝试创建一个子类
>>> from pmr2.z3cform.page import TraversePage >>> >>> class TestTraversePage(TraversePage): ... _template = 'Subpath is: %s' ... def template(self): ... subpath = '/'.join(self.traverse_subpath) ... return self._template % subpath
手动模拟遍历并渲染表单
>>> context = self.portal >>> request = TestRequest() >>> page = TestTraversePage(context, request) >>> p = page.publishTraverse(request, 'a') >>> p = page.publishTraverse(request, 'b') >>> print page() <h1 class="documentFirstHeading">Plone site</h1> <div id="content-core"> <div>Subpath is: a/b</div> </div>
与SimplePage示例类似,再次进行注册
>>> zope.component.provideAdapter(TestTraversePage, (None, None), ... zope.publisher.interfaces.browser.IBrowserView, ... name='pmr2z3cform-testtraversepage') ... >>> tb = Browser() >>> tb.open(context.absolute_url() + '/@@pmr2z3cform-testtraversepage' + ... '/a/b/c/some_path') >>> 'Plone - http://plone.org' in tb.contents True >>> '<div>Subpath is: a/b/c/some_path</div>' in tb.contents True
变更日志
0.3.3 - 2017-01-11
在单元测试环境中,直接使用视图应适用于plone.protect 2和3。
确保这里的本地测试用例与Products.PloneHotfix20160830引入的修复兼容。
更新keyring支持以处理匿名测试用户,以便遵循相同的逻辑。
0.3 - 2017-01-05
支持由plone.protect>3和plone.keyring>3引入的表单特定keyring;也支持回退。
0.2.1 - 2013-10-24
打包修复;这是为了措辞和更干净的通用设置集成。
0.2 - 2013-07-09
现在提供定制的ploneform宏,这些宏已从pmr2.app模块迁移而来。
使用Bootstrap类
已移除过时的zope.app.*导入。
0.1 - 2013-01-17
pmr2库的各种辅助表单和视图类的初始发布。
提供可以适应多个包装模板的包装BrowserView类,就像plone.z3cform所做的那样,以便视图不会调用可能由于缺少完整门户而不可用的项目。
项目详情
pmr2.z3cform-0.3.3.tar.gz 的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | b2803aa70591fe9ea603543f6283fd16ec527423bf6c9047573190c31770947c |
|
MD5 | 19afca33547897fc9112d6b05f728cd9 |
|
BLAKE2b-256 | 0541c1872ec3458d1a03f2466617fff3acf7599216415b750c690829d1746cc7 |