为pmr2定制z3c.form和plone.z3cform库

pmr2.z3cform的Python项目详细描述


简介

这个包扩展了z3c.form和plone.z3cform,以便在pmr2中使用 以及相关的图书馆。此软件包试图解决的问题是:

  • Ensure the correct root template is adapted when forms (and views/ pages) are rendered, such that there will only be one class used for testing and production, without having to subclass for specific uses or make use of wrapper classes/methods. It may be possible to support other frameworks by registering the root view to the desired layer.
  • CSRF (Cross-Site Request Forgery) prevention via the use of appropriate form authenticators, e.g. plone.protect for Plone.
  • Offer the same adaptable browser class (pages) to standard non-form views.
  • Forms with traversal subpaths.

安装和使用

只需在设置中添加或修改install_requires选项 典型的setup.py中的函数。示例:

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年1月11日

  • 直接使用视图应该对plone.protect 2和3都有效 在unittesting环境中。
  • 确保这里的本地测试用例使用 产品.plonehotfix 20160830.
  • 更新keyring支持以处理匿名测试用户以允许 遵循同样的逻辑。

0.3-2017-01-05

  • 支持plone.protect引入的特定于窗体的键环>;3 和plone.keyring>;3;也支持回退。

0.2.1-2013年10月24日

  • 打包修复;这是为措辞和更干净的通用设置而完成的 整合。

0.2-2013年7月9日

  • 现在提供定制的ploneform宏,从 pmr2.app模块。
  • 使用引导类
  • 删除了不推荐使用的zope.app.*导入。

0.1-2013-01-17

  • PMR2的各种帮助程序窗体和视图类的初始版本 图书馆。
  • 提供一个包装好的browserview类,该类可以适应多个包装器 模板很像plone.z3cform,这样视图就不会调用 由于缺少完整门户而可能不可用的项。

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

推荐PyPI第三方库


热门话题
Android上已连接音频输入设备的java列表   java是创建类的新对象还是使用静态方法?   Java:Shift/Rotate对象数组   Java Casting ArrayIterator<Object>   在java中返回布尔值时出错   无法确定文本文件读入程序(java)中的各种元素   Java Swing JToolBar   JAVAlang.IllegalStateException执行Ghost4J(Linux 32对64位)   jvm如何增加ubuntu系统的java堆化?   java CORS策略“AccessControlAllowOrigin”(Anguar 8和Servlet)   使用dagger 2的java视图依赖项注入   单元测试中RxJava的java模拟活动生命周期   arraylist中的Java打印字符串   java返回值显示为0.0。为什么会这样?   java是clientserver应用程序所必需的MVC吗?   ByteToMessageDecoder类中的java内存泄漏   java将大量文档写入firestore   GWT项目中的java TomcatMaven插件。两者之间的区别是什么:org。科德豪斯。魔咒和组织。阿帕奇。公猫maven插件   java swing:向JTree项添加自定义图形按钮