{ "info": { "author": "podhmo", "author_email": "UNKNOWN", "bugtrack_url": null, "classifiers": [ "Programming Language :: Python", "Programming Language :: Python :: Implementation :: CPython" ], "description": "marshmallow-form\n========================================\n\nmotivation\n----------------------------------------\n\nform library is not validation library\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nWhat is form library?\n\n- anyone says, 'it is validation library for post/get data'\n- another says, 'it is rendering library for form element'\n\nmarshmallow-form is not above one.\nform library is 'a container for presentation metadata'. so, form object is just a container.\n\n- 'rendering form element', it is a task of template library(mako, jinja2, ...).\n- 'validation post/get data', it is a task of schema library(colander, marshmallow, ...).\n\nmarshmallow-form is just a metadata container.\n\nfeatures\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n- having metadata anywhere\n- nested field support\n- accessing schema\n- building your own form library\n\n\ngetting started\n----------------------------------------\n\ninstall\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nfrom pypi package repository.\n\n::\n\n # pip install marshmallow-form\n\nfrom repository\n\n::\n\n git clone git@github.com/podhmo/marshmallow-form.git\n cd marshmallow-form\n python setup.py develop\n\n\nform class definition\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nthe way of form definition.\n\n.. code-block:: python\n\n import marshmallow_form as mf\n\n\n class PersonForm(mf.Form):\n name = mf.String(label=\"\u540d\u524d\", placeholder=\"foo\", widget=\"str\")\n age = mf.Integer(label=\"\u5e74\u9f62\", placeholder=\"0\", widget=\"int\")\n\n\n class ParentsForm(mf.Form):\n father = mf.Nested(PersonForm, label=\"\u7236\u89aa\")\n mother = mf.Nested(PersonForm, label=\"\u6bcd\u89aa\")\n\n- define form class with marshmallow_form.Form\n- using field classes, define form fields.\n- label and placeholder is metadata for presentation\n\n\nwith template library\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nwith template library, form is just a metadata container.\nso, a above definition, using form as metadata container.\n\n\n.. code-block:: python\n\n print(form.father.name[\"label\"]) # => '\u540d\u524d' # 'name' in japanese\n print(form.father.name[\"placeholder\"]) # => 'foo'\n print(form.name.value) # => 'foo'\n\n- accessing metadata with `__getitem__`.\n- accessing initial data or passed data with `.value`\n\n\nwith template(mako). deciding rendering method, using `widget` metadata.\n\n.. code-block:: python\n\n from mako.template import Template\n\n template = Template(\"\"\"\n <%def name=\"field(f)\">\\\n ${getattr(self, \"field_\" + f[\"widget\"])(f)}\n %def>\n\n <%def name=\"field_str(f)\">\\\n \n %def>\n\n <%def name=\"field_int(f)\">\\\n \n %def>\n\n
\n \"\"\")\n\n print(template.render(form=form))\n\noutput.\n\n.. code-block:: html\n\n \n\nvalidation\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code-block:: python\n\n from marshmallow.validate import Length\n from marshmallow import ValidationError\n\n\n class MLength(Length):\n message_min = 'Too short! {min}.'\n message_max = 'Too long! {max}.'\n\n\n class AuthenticationForm(mf.Form):\n name = mf.String()\n password = mf.String(validate=MLength(5))\n password_confirm = mf.String()\n\n @mf.Form.validator\n def same(schema, data):\n if data[\"password\"] != data[\"password_confirm\"]:\n raise ValidationError(\"not same!\", \"password\")\n\n\n input_data = {\"name\": \"foo\", \"password\": \"*\", \"password_confirm\": \"+\"}\n form = AuthenticationForm(input_data)\n print(form.validate()) # False\n print(form.errors) # {'password': ['Too short! 5.', 'not same!']}\n {'password': ['Too short! 5.', 'not same!']}\n\n\ndetail\n----------------------------------------\n\nhaving metadata anywhere\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n- form metadata\n- field metadata\n- metadata inheritance\n- metadata override\n\nform metadata\n\n.. code-block:: python\n\n import marshmallow_form as mf\n\n\n class MyForm(mf.Form):\n name = mf.Str()\n\n class Meta:\n metadata = {\"action\": \"#\"}\n\n form = MyForm()\n form[\"action\"] # => #\n form.metadata[\"method\"] = \"post\"\n form[\"method\"] # => \"post\"\n\n MyForm()[\"method\"] # => \"\"\n\n\nfield metadata\n\n.. code-block:: python\n\n class MyForm2(mf.Form):\n name = mf.Str()\n ctime = mf.DateTime(disable=True)\n\n\n form = MyForm2()\n form.ctime[\"disable\"] # => True\n\nmetadata inheritance\n\n.. code-block:: python\n\n from functools import partial\n DateTime = partial(mf.DateTime, widget=\"tdcalendar\")\n\n\n class MyForm3(mf.Form):\n ctime = DateTime()\n utime = DateTime()\n\n form = MyForm3()\n form.ctime[\"widget\"] # => \"tdcalendar\"\n form.utime[\"widget\"] # => \"tdcalendar\"\n\nmetadata override\n\n.. code-block:: python\n\n class MyForm4(MyForm3):\n class Meta:\n overrides = {\"ctime\": {\"widget\": \"mycalendar\"}}\n\n\n form = MyForm4()\n form.ctime[\"widget\"] # => \"mycalendar\"\n form.utime[\"widget\"] # => \"tdcalendar\"\n\nor with nested\n\n.. code-block:: python\n\n class PersonForm(mf.Form):\n name = mf.String(label=\"\u540d\u524d\", placeholder=\"foo\", widget=\"str\")\n age = mf.Integer(label=\"\u5e74\u9f62\", placeholder=\"0\", widget=\"int\")\n\n\n class ParentsForm(mf.Form):\n father = mf.Nested(PersonForm, label=\"\u7236\u89aa\", overrides={\"name\": {\"label\": \"\u7236\u89aa\u306e\u540d\u524d\"}})\n mother = mf.Nested(PersonForm, label=\"\u6bcd\u89aa\")\n\n form = ParentsForm()\n form.father[\"label\"] # => \"\u7236\u89aa\"\n form.father.name[\"label\"] # => \"\u7236\u89aa\u306e\u540d\u524d\"\n form.mother.name[\"label\"] # => \"\u540d\u524d\"\n\n\ndynamic form\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n- modify field\n- add field\n- remove field\n\nmodify field\n\n.. code-block:: python\n\n form = StudentForm()\n form.color.metadata[\"pairs\"] = [(\"red\", \"red\"), (\"blue\", \"blue\")]\n form.color[\"pairs\"] # => [('red', 'red'), ('blue', 'blue')]\n\n\nadd field\n\n.. code-block:: python\n\n class StudentForm(mf.Form):\n color = mf.Select([])\n name = mf.Str()\n\n form = StudentForm(initial={\"grade\": 3})\n form.add_field(\"grade\", mf.Int(label=\"\u5b66\u5e74\"))\n form.grade.value # => 3\n form.grade[\"label\"] # => \"\u5b66\u5e74\"\n\n [f.name for f in form] # => ['color', 'name', 'grade']\n\nremove field\n\n.. code-block:: python\n\n form = StudentForm()\n form.remove_field(\"color\")\n\n [f.name for f in form] # => ['name']\n\n\n\naccessing schema\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n- schema class\n- schema instance\n\nschema class\n\n.. code-block:: python\n\n from collections import namedtuple\n Person = namedtuple(\"Person\", \"name age\")\n\n\n class PersonForm(mf.Form):\n name = mf.Str()\n age = mf.Int()\n\n def make_object(self, data):\n return Person(**data)\n\n PersonForm.Schema # =>