{ "info": { "author": "Souheil Chelfouh", "author_email": "trollfot@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Framework :: Zope3", "Intended Audience :: Other Audience", "License :: OSI Approved :: GNU General Public License (GPL)", "Operating System :: OS Independent", "Programming Language :: Python" ], "description": "=================\ndolmen.forms.crud\n=================\n\n`dolmen.forms.crud` is a module which helps developers create their\nC.R.U.D forms using `Grok`, `zeam.form` and `dolmen.content`. It\nprovides a collection of base classes to add, edit, and access\ncontent. It provides adapters to customize the fields of a form.\n\n\nAdding view\n===========\n\n`dolmen.forms.crud` provides an abstraction for the 'adding'\naction. It allows pluggability at the container level and handles\nnaming and persistence. More explicitly, it's a named adapter that\nwill query the add form, check the constraints, choose a name (using a\nINameChooser) and finally, if everything went smoothly, add it on the\ncontext.\n\nA base adding view is registered out-of-the-box as a named traversable\nadapter called 'add'. It uses the following pattern:\n++add++factory_name. `factory_name` must be the name of a\n`dolmen.content.IFactory` component.\n\nLet's first create a container in which we'll test the adding view::\n\n >>> import dolmen.content\n >>> from dolmen.forms.crud.tests import Sietch\n\n >>> sietch = Sietch()\n >>> dolmen.content.IContent.providedBy(sietch)\n True\n \n >>> from zope.site.hooks import getSite\n >>> root = getSite()\n >>> root['sietch'] = sietch\n\nWith the container created, the adding view should be available and\noperational. Let's have a quick overview::\n \n >>> from zope.component import getMultiAdapter\n >>> from zope.publisher.browser import TestRequest\n >>> request = TestRequest()\n >>> addingview = getMultiAdapter((sietch, request), name='add')\n >>> addingview\n \n\n\nThe adding view component explicitly checks the security requirement\non the factory. To test that behavior, we set up two\naccounts. 'zope.manager' has all the permissions granted while\n'zope.manfred' only has the 'zope.View' credentials. Our factory\nexplicitly requires a 'zope.ManageContent' permission to be\ncalled. Let's try to access it with Manfred::\n\n >>> import zope.security.management as security \n >>> from zope.security.testing import Principal, Participation\n\n >>> manager = Principal('zope.manager', 'Manager')\n >>> manfred = Principal('zope.manfred', 'Manfred')\n\n >>> security.newInteraction(Participation(manfred))\n >>> addingview.traverse('fremen', [])\n Traceback (most recent call last):\n ...\n Unauthorized: requires the 'zope.ManageContent' permission.\n\n >>> security.endInteraction()\n\nManfred is not authorized, however Manager should successfully be able\nto access the addingview::\n\n >>> security.newInteraction(Participation(manager))\n >>> addingview.traverse('fremen', [])\n Traceback (most recent call last):\n ...\n NotFound: Object: , name: 'fremen'\n\nThe adding view is available for our item. Though, as we have no add form\nregistered, a NotFound error will be raised if we try to access our\ncurrent factory.\n\nLet's create and register a very basic generic crud\nadd form::\n\n >>> import dolmen.forms.crud as crud\n >>> class AddForm(crud.Add):\n ... '''Generic add form.\n ... '''\n \n >>> import grokcore.component\n >>> grokcore.component.testing.grok_component('addform', AddForm)\n True\n\n >>> addform = addingview.traverse('fremen', [])\n >>> addform\n \n\nOur AddForm is returned as we traverse toward the factory\n'fremen'.\n\nPerfect. Our adding view is ready to be used. Before testing the AddForm\nitself, let's have a try at the `add` method::\n\n >>> from dolmen.forms.crud.tests import Fremen\n\n >>> naib = Fremen()\n >>> added_item = addingview.add(naib)\n >>> added_item\n \n\nThe created content is correctly located and persisted::\n\n >>> added_item.__name__\n u'Fremen'\n >>> added_item.__parent__ is sietch\n True\n\nAs a matter of fact, a IAdding component should always be\nlocatable. Conveniently, you can access the location information::\n\n >>> addingview.__parent__\n \n >>> addingview.__name__\n u''\n\nThe `add` method checks if the constraints are respected. If the\ncontainer has defined restrictions or if some interface contract is\nviolated, we get an error::\n\n >>> from dolmen.forms.crud.tests import Harkonnen\n\n >>> rabban = Harkonnen()\n >>> addingview.add(rabban)\n Traceback (most recent call last):\n ...\n InvalidItemType: (<...Sietch object at ...>, <...Harkonnen object at ...>, (,))\n\nThe `add` method of the adding view can be called from the AddForm to delegate\nthe adding operation. The generic adding view already handles the common\noperations such as naming and persistence.\n\n\nGeneric forms\n=============\n\n\n`dolmen.forms.crud` provides a set of ready-to-use base classes that\nwill auto-generate forms based on `dolmen.content` schemas.\n\n`dolmen.forms.crud` forms are layout aware (see `megrok.layout` for\nmore info). Therefore, we need to register a basic layout in order to\nrender our forms::\n\n >>> from grokcore.layout import Layout\n >>> from zope.interface import Interface\n\n >>> class GenericLayout(Layout):\n ... grokcore.component.context(Interface)\n ...\n ... def render(self):\n ... return self.view.content()\n\n >>> grokcore.component.testing.grok_component('layout', GenericLayout)\n True\n\nThe context of the tests is our previously created content::\n\n >>> naib\n \n >>> naib.__parent__\n \n\n\nCreate\n------\n\nThe add form implementation is tightly tied to the adding view. As the add\nform behavior has been mostly covered above, we'll only test the\npresence of the fields and the label on the form itself::\n\n >>> addform = addingview.traverse('fremen', [])\n >>> addform\n \n\n >>> print addform.label\n Add: Fremen Warrior\n\n >>> addform.fields.keys()\n ['title', 'water']\n \n >>> addform.updateForm()\n >>> for action in addform.actions: print action\n \n \n\n >>> security.endInteraction()\n\nUpdate\n------\n\nAn edit form can be registered simply by sublassing the Edit base class::\n\n >>> class EditForm(crud.Edit):\n ... '''Generic edit form.\n ... '''\n\n >>> grokcore.component.testing.grok_component('editform', EditForm)\n True\n\nBy default, the registered name of an Edit form is 'edit'::\n\n >>> grokcore.component.name.bind().get(EditForm)\n 'edit'\n\nThis form registered, we can check if all the fields are ready to be\nedited::\n\n >>> post = TestRequest(form={\n ... 'form.field.water': '25',\n ... 'form.field.title': u'Stilgar',\n ... 'form.action.update': u'Update'},\n ...\t REQUEST_METHOD='POST',\n ... )\n\n >>> security.newInteraction(post)\n\n >>> editform = getMultiAdapter((naib, post), name='edit')\n >>> editform\n \n\n >>> editform.updateForm()\n >>> for action in editform.actions: print action\n \n \n\n >>> editform.fields.keys()\n ['title', 'water']\n\nThe values should now be set::\n\n >>> naib.title\n u'Stilgar'\n >>> naib.water\n 25\n\n >>> security.endInteraction()\n\nRead\n-----\n\nA special kind of form allows you display your content::\n\n >>> class DefaultView(crud.Display):\n ... '''Generic display form.\n ... '''\n \n >>> grokcore.component.testing.grok_component('display', DefaultView)\n True\n\n >>> security.newInteraction(TestRequest())\n\n >>> view = getMultiAdapter((naib, request), name='defaultview')\n >>> view\n \n\nThe Display form removes the 'title' from the list of fields. This\nparticular attribute is used directly by the template::\n\n >>> view.fields.keys()\n ['water']\n\nA display form has no actions::\n\n >>> len(view.actions)\n 0\n\n`dolmen.forms.crud` provides a very basic template for that form. As\nwe can see, the title attribute is used as the HTML header (h1) of the\npage::\n\n >>> print view()\n
\n

Stilgar

\n
\n
\n \n (required)\n
\n 25\n
\n
\n
\n\n >>> security.endInteraction()\n\nDelete\n------\n\nA delete form is a simple form with no fields, that only provides a\n'confirm' action::\n\n >>> class DeleteForm(crud.Delete):\n ... '''Generic delete form.\n ... '''\n\n >>> grokcore.component.testing.grok_component('delete_form', DeleteForm)\n True\n\n >>> deleteform = getMultiAdapter((naib, request), name='deleteform')\n >>> deleteform\n \n\n >>> deleteform.updateForm()\n >>> for action in deleteform.actions: print action\n \n \n\n >>> len(deleteform.fields)\n 0\n\nWhen confirmed, the form tries to delete the object::\n\n >>> post = TestRequest(form={\n ... 'form.action.delete': u'Delete'},\n ...\t REQUEST_METHOD='POST',\n ... )\n\n >>> security.newInteraction(post)\n\n >>> list(sietch.keys())\n [u'Fremen']\n\n >>> deleteform = getMultiAdapter((naib, post), name='deleteform')\n >>> deleteform.updateForm()\n \n >>> from zope.i18n import translate\n >>> translate(deleteform.status, context=post)\n u'The object has been deleted.'\n\n >>> list(sietch.keys())\n []\n\n >>> deleteform.response.getStatus()\n 302\n >>> deleteform.response.getHeader('location')\n 'http://127.0.0.1/sietch'\n\n >>> security.endInteraction()\n \n\nGeneric forms without Dublin Core\n=====================================\n\nTests run above where using a content defining a title, let's verify it still\nworks with bare contents.\n\n >>> sietch = root['sietch']\n\n\nCreate\n------\n\nForm customization\n==================\n\nTo customize forms, the usual solution is to subclass them and to work\nwith the subclass. `dolmen.forms.crud` proposes a new component to\ncustomize your forms. Defined by the `IFieldsCustomization` interface,\nit's an adapter that allows you to interact at the field level.\n\nIn a `IFieldsCustomization`, the customization happens at the __call__\nlevel. The forms, while they update the objects fields, query a\n`IFieldsCustomization` adapter and call it, giving the fields as an\nargument.\n\nLet's implement an example::\n\n >>> class RemoveWater(crud.FieldsCustomizer):\n ... grokcore.component.adapts(Fremen, crud.Add, None)\n ...\n ... def __call__(self, fields):\n ... \"\"\"Alters the form fields\"\"\"\n ... return fields.omit('water')\n\n >>> from zope.interface import verify\n >>> verify.verifyClass(crud.IFieldsCustomization, RemoveWater)\n True\n\nWe can now register and test the customization::\n\n >>> grokcore.component.testing.grok_component('removewater', RemoveWater)\n True\n\n >>> security.newInteraction(Participation(manager))\n\n >>> addform = addingview.traverse('fremen', [])\n >>> for field in addform.fields: print field\n \n\nOne important thing is noticeable here : the 'RemoveWater' adapter was\nregistered for the 'Fremen' component. To be able to lookup the\nregistery for suitable adapters, the add form uses a special lookup\nfunction : `dolmen.forms.crud.utils.queryClassMultiAdapter`.\n\nWe can test a more complex example, returning a brand new instance of\nFields::\n\n >>> import dolmen.forms.base\n >>> from dolmen.forms.crud.utils import getSchemaFields\n\n >>> class AddFieldToView(crud.FieldsCustomizer):\n ... grokcore.component.adapts(Fremen, crud.Display, None)\n ...\n ... def __call__(self, fields):\n ... \"\"\"Returns a new instance of Fields.\n ... \"\"\"\n ... schema = dolmen.content.get_schema(self.context)\n ... if schema:\n ... return dolmen.forms.base.Fields(*schema)\n ... return dolmen.forms.base.Fields()\n\n >>> grokcore.component.testing.grok_component('viewer', AddFieldToView)\n True\n\nChecking the fields, we should get *all* the fields defined by the\nFremen schema::\n\n >>> view = getMultiAdapter((naib, request), name='defaultview')\n >>> view.fields.keys()\n ['title', 'water']\n\n >>> security.endInteraction()\n\nEvents and field updates\n========================\n\nWhen using the generic `dolmen.forms.crud` forms, some events are\ntriggered for you. They represent the lifecycle of the manipulated object.\n\nTo check on all the events triggered, we can set up a simple event\nlogging list and a generic handler::\n\n >>> from zope.component import provideHandler\n >>> from zope.lifecycleevent import IObjectModifiedEvent\n >>> logger = []\n \n >>> def event_logger(object, event):\n ... logger.append(event)\n\n >>> provideHandler(event_logger, (Fremen, IObjectModifiedEvent))\n\n\nEditing events\n--------------\n\nLet's have the same introspection check with the edit form::\n\n >>> logger = []\n\nWe provide data for the update::\n\n >>> request = TestRequest(form={\n ... 'form.field.water': '10',\n ... 'form.field.title': u'Sihaya',\n ... 'form.action.update': u'Update'},\n ...\t REQUEST_METHOD='POST',\n ... )\n\n >>> security.newInteraction(request)\n\n >>> chani = Fremen()\n >>> root['chani'] = chani\n\n >>> editform = getMultiAdapter((chani, request), name='edit')\n >>> editform.updateForm()\n\nWe check the trigged events::\n\n >>> for event in logger: print event\n <...ObjectModifiedEvent object at ...>\n\nIn depth, we can check if the updated fields are correctly set in the\nevent's descriptions::\n\n >>> for desc in logger[0].descriptions:\n ... print \"%r: %s\" % (desc.interface, desc.attributes)\n : ('water', 'title')\n\n >>> chani.title\n u'Sihaya'\n >>> chani.water\n 10\n\n >>> security.endInteraction()\n\nField update\n------------\n\n`dolmen.forms.base` provides the description of a new component that\ncan be used to atomize the updating process of an object:\n`IFieldUpdate`. An implementation is available in `dolmen.forms.crud`,\nusing an event handler, listening on ObjectModifiedEvent and\nObjectCreatedEvent::\n\n >>> updates = []\n\n >>> from zope.schema import TextLine\n >>> from zope.component import adapter, provideAdapter\n >>> from zope.interface import implementer\n >>> from dolmen.forms.base import IFieldUpdate\n\n >>> @implementer(IFieldUpdate)\n ... @adapter(Fremen, TextLine)\n ... def updated_textfield(context, field):\n ... updates.append((context, field))\n\n >>> provideAdapter(updated_textfield, name=\"updatetext\")\n\n\nUsing an add form, the IFieldUpdate adapters should be called during an objects creation::\n\n >>> request = TestRequest(form={\n ... 'form.field.title': u'Liet',\n ... 'form.action.add': u'Add'},\n ...\t REQUEST_METHOD='POST',\n ... )\n\n >>> request.setPrincipal(manager)\n >>> interaction = security.newInteraction(request)\n\n >>> desert = root['desert'] = dolmen.content.Container()\n >>> addingview = getMultiAdapter((desert, request), name='add')\n >>> addform = addingview.traverse('fremen', [])\n >>> addform.updateForm()\n\n >>> kynes = desert['Fremen']\n >>> kynes\n \n >>> kynes.title\n u'Liet' \n\n >>> print updates\n [(,\n )]\n\n >>> security.endInteraction()\n\n\nWe can do the same thing for the edit form::\n\n >>> updates = []\n\n >>> request = TestRequest(form={\n ... 'form.field.water': '50',\n ... 'form.field.title': u'Imperial weather specialist',\n ... 'form.action.update': u'Update'},\n ...\t REQUEST_METHOD='POST',\n ... )\n\n >>> request.setPrincipal(manager)\n >>> security.newInteraction(request)\n\n >>> editform = getMultiAdapter((kynes, request), name='edit')\n >>> editform.updateForm()\n\n >> kynes.title\n u'Imperial weather specialist'\n\n >>> updates\n [(, )]\n\nUpdating a field without a registered IFieldUpdate adapter shouldn't do\nanything::\n\n >>> updates = []\n\n >>> request = TestRequest(form={\n ... 'form.field.water': '40',\n ... 'form.action.update': u'Update'},\n ...\t REQUEST_METHOD='POST',\n ... )\n\n >>> editform = getMultiAdapter((kynes, request), name='edit')\n >>> editform.updateForm()\n\n >>> updates\n []\n\n\nChangelog\n=========\n\n1.0 (2012-10-24)\n----------------\n\n* Fixed the dependencies and the testing, echoing the changes in the related\n packages.\n\n\n1.0b5 (2011-02-16)\n------------------\n\n* We now use the new `get_schema` util function from\n ``dolmen.content`` to get the `schema` value. This allows a\n normalized way to deal with schema retrieval.\n\n\n1.0b4 (2011-02-16)\n------------------\n\n* Corrected event triggering that used to fail if the `IContent` object\n had no schema defined.\n\n\n1.0b3 (2011-02-14)\n------------------\n\n* Added a util function that returns a `Fields` instance, given a\n form, a context and a list of omitted fields' name.\n* Objects or classes with no schema are now supported.\n* We now use the `getContent` method of the form to get the\n `Edit`, `Display`, `Delete` forms' context.\n\n\n1.0b2 (2011-02-14)\n------------------\n\n* Adapted to echo the latest ``dolmen.content`` changes.\n* `title` is now obtained thanks to `DCDescriptiveProperties` from\n ``zope.dublincore`` (for the labels).\n* Adapted the tests for the latest ``zeam.form.base`` changes.\n\n\n1.0b1 (2010-07-13)\n------------------\n\n* Using latest dolmen.content changes, to display a sane form label.\n* Added correct translations.\n* Forms mode are now using mode markers.\n\n\n1.0a3 (2010-06-25)\n------------------\n\n* Added missing translations (french)\n* Actions now use the form `getContent` method, to get the proper form\n content. In addition, the content is now tested, to handle\n DataManagers. Import fix : the Delete action now behaves properly.\n* Using the latest version of ``dolmen.forms.base`` with improved\n errors handling and data processing and notification.\n\n\n1.0a2 (2010-06-05)\n------------------\n\n* Added the CancelAction to the input forms.\n* Fixed a bug where the errors where not set correctly on submission\n failure.\n\n\n1.0a1 (2010-06-03)\n------------------\n\n* The package is now using `zeam.form` instead of `z3c.form`.\n* Added internationalization (French, English)\n* The IObjectInitializedEvent has been removed, as we are now using\n dolmen.content >= 0.3.1. It has been replaced by a simple\n IObjectAddedEvent. The IFieldUpdate triggers have been modified\n accordingly.\n\n\n0.4.0 (2010-02-22)\n------------------\n\n* Cleaned dependencies and tests. The package is now 100% zope.app\n free.\n\n\n0.3.0 (2009-11-02)\n------------------\n\n* Removed dependencies on zope.app.container.\n* Upgraded to use ZTK versions (1.0dev).\n\n\n0.2.1 (2009-11-02)\n------------------\n\n* The Delete form is now using class level messages for success and\n failure.\n* Updated tests to cover the deletion bug.\n* Corrected the redirection URL after a delete action.\n\n\n0.2.0 (2009-11-02)\n------------------\n\n* Added a DeleteForm\n* Added titles to all the forms\n* Corrected double nextURL method in the EditForm.\n\n\n0.1.0 (2009-10-26)\n------------------\n\n* Initial release", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://www.dolmen-project.org", "keywords": "Dolmen Grok Content Forms", "license": "GPL", "maintainer": null, "maintainer_email": null, "name": "dolmen.forms.crud", "package_url": "https://pypi.org/project/dolmen.forms.crud/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/dolmen.forms.crud/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://www.dolmen-project.org" }, "release_url": "https://pypi.org/project/dolmen.forms.crud/1.0/", "requires_dist": null, "requires_python": null, "summary": "CRUD forms and actions for `dolmen.content`", "version": "1.0" }, "last_serial": 791335, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "b30f84d057faa5421b4200022fcefda2", "sha256": "250a9a48e7dc059e6a600d9faeec79dfdbfc9dfe86bf9b0d0fbf247b642004c0" }, "downloads": -1, "filename": "dolmen.forms.crud-0.1.tar.gz", "has_sig": false, "md5_digest": "b30f84d057faa5421b4200022fcefda2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17041, "upload_time": "2009-10-27T00:31:40", "url": "https://files.pythonhosted.org/packages/72/c9/16c5631213f48c2acce30fcdff6423272c995eae0be84f6442e3655b6585/dolmen.forms.crud-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "8a9dae0935e29b030e391165eb1766ab", "sha256": "aeeef5e491efa06de48d73bbfaf87553cc78d76102c917b5e798445acc27d70f" }, "downloads": -1, "filename": "dolmen.forms.crud-0.2.tar.gz", "has_sig": false, "md5_digest": "8a9dae0935e29b030e391165eb1766ab", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13000, "upload_time": "2009-11-02T16:34:54", "url": "https://files.pythonhosted.org/packages/57/5b/e7d2d40c0dbdfb9d817b08a9edad92a730007f412ddbdd36026b47916800/dolmen.forms.crud-0.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "92b4847fdba809540b035019d4b636e4", "sha256": "3b47493980046ea54b169cb7fad8d8f99ef32d4c2b791294cc10eeb69fc0d48d" }, "downloads": -1, "filename": "dolmen.forms.crud-0.2.1.tar.gz", "has_sig": false, "md5_digest": "92b4847fdba809540b035019d4b636e4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13320, "upload_time": "2009-11-02T18:43:49", "url": "https://files.pythonhosted.org/packages/27/5b/42eb037d68d30b0c417fa11351f46e36e10bbccaa2358b6e460969f7a4f6/dolmen.forms.crud-0.2.1.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "06b208cd1f8bcb959ad26f165cd33468", "sha256": "dc57934ed555097a6bf0768a2aaf59fc89d95af086297c031218b493c06e4ee0" }, "downloads": -1, "filename": "dolmen.forms.crud-0.3.tar.gz", "has_sig": false, "md5_digest": "06b208cd1f8bcb959ad26f165cd33468", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14677, "upload_time": "2009-11-18T16:55:36", "url": "https://files.pythonhosted.org/packages/7f/09/8e305f725b3e2a4975bc22becc119bf6f5ece355cb31fcda12ec5a6573f4/dolmen.forms.crud-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "d01c93862aa7238630739bee07764437", "sha256": "f9785bdb6b916b172931f691c96ee110df9887e7b15bfb89d93f1bdab79f387f" }, "downloads": -1, "filename": "dolmen.forms.crud-0.4.tar.gz", "has_sig": false, "md5_digest": "d01c93862aa7238630739bee07764437", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19375, "upload_time": "2010-02-22T13:02:32", "url": "https://files.pythonhosted.org/packages/66/ac/84109191ea7dac2ebc598b27fd71d4338ddc26ff238d3ea727b04b298295/dolmen.forms.crud-0.4.tar.gz" } ], "1.0": [ { "comment_text": "", "digests": { "md5": "7b1e6d993557626074299ffe218afbf1", "sha256": "4e7fcd350a42fb25949606c2d4052be27640d7df21fffa44b8800b2334806cc7" }, "downloads": -1, "filename": "dolmen.forms.crud-1.0.tar.gz", "has_sig": false, "md5_digest": "7b1e6d993557626074299ffe218afbf1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24109, "upload_time": "2012-10-24T08:29:52", "url": "https://files.pythonhosted.org/packages/ee/70/ca0c19ab78b584eaded2adc5012276801e1a3e09172db9499d472d576ba4/dolmen.forms.crud-1.0.tar.gz" } ], "1.0a1": [ { "comment_text": "", "digests": { "md5": "4f63d1340821a8c19980ce76bd946df8", "sha256": "49c9680486ab4de6265482eab48c57c77f1721d44419427de63796dbb02b538b" }, "downloads": -1, "filename": "dolmen.forms.crud-1.0a1.tar.gz", "has_sig": false, "md5_digest": "4f63d1340821a8c19980ce76bd946df8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18969, "upload_time": "2010-06-03T00:19:01", "url": "https://files.pythonhosted.org/packages/3d/aa/ebe0a4f1f20ee11de8310433ca1f9f4e632dbd9cd946e405bf5efce0c7d1/dolmen.forms.crud-1.0a1.tar.gz" } ], "1.0a2": [ { "comment_text": "", "digests": { "md5": "e2e4fcc8ed8dd12dca4ee05e13cc2cc7", "sha256": "1d83c6d2c8856390f195fbbfa96fa53197f37310a94e2b7d58ecf7a371fda476" }, "downloads": -1, "filename": "dolmen.forms.crud-1.0a2.tar.gz", "has_sig": false, "md5_digest": "e2e4fcc8ed8dd12dca4ee05e13cc2cc7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19299, "upload_time": "2010-06-05T01:43:33", "url": "https://files.pythonhosted.org/packages/73/0c/5e4af50de4d739a06c8a1cde697e1770576ea8aa9e1ce5e03cc5fb82ba01/dolmen.forms.crud-1.0a2.tar.gz" } ], "1.0a3": [ { "comment_text": "", "digests": { "md5": "e5203fc47fe8df3ebe33717dd9b2f5f5", "sha256": "5c89c57292e5e1e5a4d3df2762d3479fd88bc6fff6c52d2ee068e48075c54ee4" }, "downloads": -1, "filename": "dolmen.forms.crud-1.0a3.tar.gz", "has_sig": false, "md5_digest": "e5203fc47fe8df3ebe33717dd9b2f5f5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19900, "upload_time": "2010-06-25T15:31:46", "url": "https://files.pythonhosted.org/packages/d3/60/4c5829c6a2295ba0d660a7b8befd3086a3c2d686a18c5f5affe9056683e1/dolmen.forms.crud-1.0a3.tar.gz" } ], "1.0b1": [ { "comment_text": "", "digests": { "md5": "99c07760f1b4a3cc3d00feb21d0df228", "sha256": "d9d0d92b0374aea803138a88dcef04989a70624f85f30234259aa94100e1e85a" }, "downloads": -1, "filename": "dolmen.forms.crud-1.0b1.tar.gz", "has_sig": false, "md5_digest": "99c07760f1b4a3cc3d00feb21d0df228", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21196, "upload_time": "2010-07-13T19:23:41", "url": "https://files.pythonhosted.org/packages/94/3d/b44a5871f5e9c880ebce37cd2ffa924a56593ede4bafdec37536abcca757/dolmen.forms.crud-1.0b1.tar.gz" } ], "1.0b2": [ { "comment_text": "", "digests": { "md5": "54f786a52a5e0985be9eb4482158be54", "sha256": "89e50aa15852f7720c8d47186cb8b72d54fa3daa419eb684db6f5eed0722e60f" }, "downloads": -1, "filename": "dolmen.forms.crud-1.0b2.tar.gz", "has_sig": false, "md5_digest": "54f786a52a5e0985be9eb4482158be54", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22312, "upload_time": "2011-02-14T14:17:23", "url": "https://files.pythonhosted.org/packages/30/6e/6ad668e090cd40a51e57cb80fdb109b8fa8890b0e45af64968808dcec5b1/dolmen.forms.crud-1.0b2.tar.gz" } ], "1.0b3": [ { "comment_text": "", "digests": { "md5": "c72cb6f430fccaf59d144f3653aa11a1", "sha256": "6d5984c4d0f464441592c77e94e0cfca56f30d70aa8a0c2f14fc9c3095e9f5a9" }, "downloads": -1, "filename": "dolmen.forms.crud-1.0b3.tar.gz", "has_sig": false, "md5_digest": "c72cb6f430fccaf59d144f3653aa11a1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23046, "upload_time": "2011-02-14T18:02:47", "url": "https://files.pythonhosted.org/packages/1b/fa/59f012b204bc078c982d4c2068d3fefd860084147a4010ddb66a27806e87/dolmen.forms.crud-1.0b3.tar.gz" } ], "1.0b4": [ { "comment_text": "", "digests": { "md5": "88cd13ae8c60eaa49996698f5cdc72a9", "sha256": "4a5054b6cb3008f032187739b53909062d48cc6f4f08025182d7b755faa889b1" }, "downloads": -1, "filename": "dolmen.forms.crud-1.0b4.tar.gz", "has_sig": false, "md5_digest": "88cd13ae8c60eaa49996698f5cdc72a9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23230, "upload_time": "2011-02-16T10:35:19", "url": "https://files.pythonhosted.org/packages/74/a1/aff3e0ebc10381135a2c832402f2b60e78c6b2bd22dd83c2b960593f5172/dolmen.forms.crud-1.0b4.tar.gz" } ], "1.0b5": [ { "comment_text": "", "digests": { "md5": "4b477457c5a372594f5291cfc346c8c7", "sha256": "4f4ff9537814b86ae4f4f79629fb81da555d641ef46e6555df19197a1994a135" }, "downloads": -1, "filename": "dolmen.forms.crud-1.0b5.tar.gz", "has_sig": false, "md5_digest": "4b477457c5a372594f5291cfc346c8c7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23740, "upload_time": "2011-02-16T21:14:02", "url": "https://files.pythonhosted.org/packages/68/8f/a53f221ec22243c1e56727a82344b262331c82a6a1ddf8032a7b1ac78078/dolmen.forms.crud-1.0b5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7b1e6d993557626074299ffe218afbf1", "sha256": "4e7fcd350a42fb25949606c2d4052be27640d7df21fffa44b8800b2334806cc7" }, "downloads": -1, "filename": "dolmen.forms.crud-1.0.tar.gz", "has_sig": false, "md5_digest": "7b1e6d993557626074299ffe218afbf1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24109, "upload_time": "2012-10-24T08:29:52", "url": "https://files.pythonhosted.org/packages/ee/70/ca0c19ab78b584eaded2adc5012276801e1a3e09172db9499d472d576ba4/dolmen.forms.crud-1.0.tar.gz" } ] }