From bba966892634c0c91907ad566beafbebdab33df1 Mon Sep 17 00:00:00 2001 From: Artur Barseghyan Date: Thu, 1 Jun 2017 01:18:59 +0200 Subject: [PATCH] prepare 0.11.12 --- CHANGELOG.rst | 7 + TODOS.rst | 3 + docs/index.rst | 4001 ----------------- setup.py | 2 +- src/fobi/__init__.py | 4 +- .../contrib/apps/drf_integration/TODOS.rst | 5 + src/fobi/contrib/apps/drf_integration/base.py | 3 +- .../contrib/apps/drf_integration/dynamic.py | 55 +- .../content/content_image/base.py | 12 +- .../content/content_image_url/base.py | 12 +- .../content/content_text/base.py | 13 +- .../content/content_video/base.py | 12 +- .../form_elements/fields/decimal/base.py | 10 +- .../form_elements/fields/email/base.py | 8 +- .../form_elements/fields/float/base.py | 7 +- .../form_elements/fields/input/base.py | 48 +- .../form_elements/fields/integer/base.py | 14 +- .../form_elements/fields/ip_address/base.py | 6 +- .../form_elements/fields/password/base.py | 6 +- .../form_elements/fields/regex/base.py | 7 +- .../form_elements/fields/slug/base.py | 6 +- .../form_elements/fields/text/base.py | 7 +- .../form_elements/fields/textarea/base.py | 6 +- .../form_elements/fields/url/base.py | 6 +- .../contrib/apps/drf_integration/metadata.py | 31 +- .../apps/drf_integration/serializers.py | 8 + .../contrib/apps/drf_integration/views.py | 5 +- src/fobi/tests/data.py | 11 +- 28 files changed, 259 insertions(+), 4056 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ae236e9c9..f038ce096 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,13 @@ are used for versioning (schema follows below): 0.3.4 to 0.4). - All backwards incompatible changes are mentioned in this document. +0.11.12 +------- +2017-05-31 + +- Added a lot of field metadata to the OPTIONS call of ``drf_integration`` app. +- Appended a lot of sub-module README files to the main documentation. + 0.11.11 ------- 2017-05-29 diff --git a/TODOS.rst b/TODOS.rst index 9301f370b..db585f470 100644 --- a/TODOS.rst +++ b/TODOS.rst @@ -81,6 +81,9 @@ Roadmap Uncategorised ------------- +- Somehow PyPy started to fail under Django 1.10 and 1.11 (invocation error), + so it must be some package incompatibility/installation problems. Find out + why. - Think of moving the translation strings from in stored-in=database level to lazily-translated level (so that in some plugins, for instance - in database translations happen lazily). For mail plugin that should not be the case, diff --git a/docs/index.rst b/docs/index.rst index 8d3e57430..3cf6119b7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -2368,8 +2368,6 @@ Author ====== Artur Barseghyan - - Screenshots =========== Bootstrap3 theme @@ -2504,8 +2502,6 @@ View/edit form .. image:: _static/simple/06_view_form.png :scale: 80 % - - Documentation ============= Contents: @@ -2525,4000 +2521,3 @@ Indices and tables * :ref:`modindex` * :ref:`search` - - -(Sub)modules -============ -Some additional documentation on ``django-fobi`` sub-modules are listed -below. - - -fobi.contrib.apps.djangocms_integration ---------------------------------------- -A ``django-fobi`` integration with DjangoCMS. - -Prerequisites -~~~~~~~~~~~~~ -Has been tested with DjangoCMS 2.4.3 and 3.0.6 only. Might work on earlier (or -later) versions as well. - -Installation -~~~~~~~~~~~~ -Versions -######## -See the requirements files: - -- `DjangoCMS 2.4.3 requirements - `_. -- `DjangoCMS 3.0.6 requirements - `_. - -your_project/settings.py -######################## -See the example settings files: - -- `DjangoCMS 2.4.3 settings - `_. -- `DjangoCMS 3.0.6 settings - `_. - -.. code-block:: python - - INSTALLED_APPS = list(INSTALLED_APPS) - INSTALLED_APPS += [ - 'cms', # FeinCMS - - 'fobi.contrib.apps.djangocms_integration', # Fobi DjangoCMS app - ] - -Information for developers -~~~~~~~~~~~~~~~~~~~~~~~~~~ -Templates for DjangoCMS -####################### -Django-CMS templates are quite specific and in some aspects are not 100% -compatible with built-in themes (due to the fact that DjangoCMS intensively -makes use of ``django-sekizai`` which isn't used in the generic templates). - -That does not anyhow affect the core ``fobi`` and the built-in themes, -although you can't magically reuse built-in ``fobi`` themes with Django-CMS -(as it's done for `FeinCMS page templates -`_). - -You would have to make custom page templates from scratch (or based on a -copy of the desired bundled template). See how I did it for all bundled themes -`here -`_: - -- `Bootstrap 3 - `_ -- `Foundation 5 - `_ -- `Simple - `_ - -Template rendering -################## -The embed DjangoCMS widget is rendered with use of two theme templates: - -- ``view_embed_form_entry_ajax_template``: Used for rendering the form. -- ``embed_form_entry_submitted_ajax_template``: Used for rendering the form - sent event. - -Using custom templates for rendering the widget -############################################### -In the widget, you can specify a template which you want to be used for -rendering the form or the form-sent event. - -Example: - -.. code-block:: python - - FOBI_DJANGOCMS_INTEGRATION_FORM_TEMPLATE_CHOICES = ( - ("yourapp/custom_view_embed_form_v1.html", - "Custom embed form view template #1"), - ("yourapp/custom_view_embed_form_v2.html", - "Custom embed form view template #2"), - ) - -Same goes for form-sent templates. - -.. code-block:: python - - FOBI_DJANGOCMS_INTEGRATION_SUCCESS_PAGE_TEMPLATE_CHOICES = ( - ("yourapp/custom_embed_form_submitted_v1.html", - "Custom form-sent template #1"), - ("yourapp/custom_embed_form_submitted_v2.html", - "Custom form-sent template #2"), - ) - -Registering a template in the ``FORM_TEMPLATE_CHOICES`` makes it available -for all the themes. If you rather want to use different custom templates -for different themes, use the ``FOBI_CUSTOM_THEME_DATA`` as shown in the -example below. - -.. code-block:: python - - FOBI_CUSTOM_THEME_DATA = { - 'bootstrap3': { - 'djangocms_integration': { - 'form_template_choices': [ - ('fobi/bootstrap3_extras/view_embed_form.html', - "Custom bootstrap3 embed form view template"), - ], - 'success_page_template_choices': [ - ('fobi/bootstrap3_extras/embed_form_submitted.html', - "Custom bootstrap3 embed form entry submitted template"), - ], - }, - }, - 'foundation5': { - 'djangocms_integration': { - 'form_template_choices': [ - ('fobi/foundation5_extras/view_embed_form.html', - "Custom foundation5 embed form view template"), - ], - 'success_page_template_choices': [ - ('fobi/foundation5_extras/embed_form_submitted.html', - "Custom foundation5 embed form entry submitted template"), - ], - }, - }, - } - -Usage -~~~~~ -The ``fobi.contrib.apps.djangocms_integration.models.FobiFormWidget`` consists -of the following fields: - -- Form: The form to be used. -- Form template name: Template to be used to render the embed form. -- Hide form title: If checked, no form title would be shown. -- Form title: Overrides the standard form title. -- Submit button text: Overrides the default submit button text. -- Success page template name: Template to be used to render the embed form-sent - event. -- Hide success page title: If checked, no form-sent title would be shown. -- Success page title: Overrides the form-sent title. -- Success page text: Overrides the form-sent text. - - -fobi.contrib.apps.drf_integration ---------------------------------- -A ``django-fobi`` integration with ``Django REST framework``. - -Supported actions are: - -- `LIST`_: List all the forms. -- `OPTIONS`_: Describe the given form. -- `PUT`_: Submit form data. - -Live demo -~~~~~~~~~ -Live demo is available on Heroku. - -- `The core `_ -- `Django REST framework integration `_ - -Supported fields -~~~~~~~~~~~~~~~~ -The following fields are supported. - -Content (presentational form elements) -###################################### -Unlike standard fields, ``content`` fields are purely presentational. -You're not supposed to make write actions on them (it won't work). Neither -will they be displayed in the browsable API (list/retrieve actions). However, -they will be listed in the options action call. All content fields are of type -"content". - -- content_image -- content_image_url -- content_text -- content_video - -Fields -###### -- boolean -- checkbox_select_multiple -- date -- date_drop_down -- datetime -- decimal -- email -- file -- float -- hidden (in terms of the Django REST framework - a read-only field) -- input (some sort of a copy of ``text`` plugin) -- integer -- ip_address -- null_boolean -- password (some sort of a copy of ``text`` plugin) -- radio -- range_select -- regex -- select -- select_multiple -- select_multiple_with_max -- slider (just a copy of range_select, for compatibility with main package) -- slug -- text -- textarea (some sort of a copy of ``text`` plugin) -- time -- url - -Not (yet) supported fields -~~~~~~~~~~~~~~~~~~~~~~~~~~ -The following fields are not supported. Those marked with asterisk are planned -to be supported in the upcoming releases. - -- select_model_object -- select_mptt_model_object -- select_multiple_model_objects -- select_multiple_mptt_model_objects - -Implementation details -~~~~~~~~~~~~~~~~~~~~~~ -Each ``django-fobi`` plugin has its' own representative integration plugin -within ``fobi.contrib.aps.drf_integration`` package. - -Some of the plugins may seam to have zero-added-value and in fact they are. -For instance, DRF integration ``slider`` plugin is just an exact copy of the -``range_select`` plugin, created in order to provide exactly the same form -fields generated in the API. - -You should mention all the plugins you want to use explicitly in the -project settings. Thus, if you have used (included in the ``INSTALLED_APPS``) -the core plugins: - -- fobi.contrib.plugins.form_elements.fields.boolean -- fobi.contrib.plugins.form_elements.fields.checkbox_select_multiple -- fobi.contrib.plugins.form_elements.fields.date -- fobi.contrib.plugins.form_elements.fields.date_drop_down -- fobi.contrib.plugins.form_elements.fields.datetime -- fobi.contrib.plugins.form_elements.fields.decimal -- fobi.contrib.plugins.form_elements.fields.email -- fobi.contrib.plugins.form_elements.fields.file -- fobi.contrib.plugins.form_elements.fields.float -- fobi.contrib.plugins.form_elements.fields.hidden -- fobi.contrib.plugins.form_elements.fields.input -- fobi.contrib.plugins.form_elements.fields.integer -- fobi.contrib.plugins.form_elements.fields.ip_address -- fobi.contrib.plugins.form_elements.fields.null_boolean -- fobi.contrib.plugins.form_elements.fields.password -- fobi.contrib.plugins.form_elements.fields.radio -- fobi.contrib.plugins.form_elements.fields.range_select -- fobi.contrib.plugins.form_elements.fields.regex -- fobi.contrib.plugins.form_elements.fields.select -- fobi.contrib.plugins.form_elements.fields.select_multiple -- fobi.contrib.plugins.form_elements.fields.select_multiple_with_max -- fobi.contrib.plugins.form_elements.fields.slider -- fobi.contrib.plugins.form_elements.fields.slug -- fobi.contrib.plugins.form_elements.fields.text -- fobi.contrib.plugins.form_elements.fields.textarea -- fobi.contrib.plugins.form_elements.fields.time -- fobi.contrib.plugins.form_elements.fields.url -- fobi.contrib.plugins.form_elements.content.content_image -- fobi.contrib.plugins.form_elements.content.content_image_url -- fobi.contrib.plugins.form_elements.content.content_text -- fobi.contrib.plugins.form_elements.content.content_video -- fobi.contrib.plugins.form_handlers.db_store -- fobi.contrib.plugins.form_handlers.http_repost -- fobi.contrib.plugins.form_handlers.mail - -You should include their correspondent Django REST framework implementations -in the ``INSTALLED_APPS`` as well: - -- fobi.contrib.apps.drf_integration.form_elements.fields.boolean -- fobi.contrib.apps.drf_integration.form_elements.fields.checkbox_select_multiple -- fobi.contrib.apps.drf_integration.form_elements.fields.date -- fobi.contrib.apps.drf_integration.form_elements.fields.date_drop_down -- fobi.contrib.apps.drf_integration.form_elements.fields.datetime -- fobi.contrib.apps.drf_integration.form_elements.fields.decimal -- fobi.contrib.apps.drf_integration.form_elements.fields.email -- fobi.contrib.apps.drf_integration.form_elements.fields.file -- fobi.contrib.apps.drf_integration.form_elements.fields.float -- fobi.contrib.apps.drf_integration.form_elements.fields.hidden -- fobi.contrib.apps.drf_integration.form_elements.fields.input -- fobi.contrib.apps.drf_integration.form_elements.fields.integer -- fobi.contrib.apps.drf_integration.form_elements.fields.ip_address -- fobi.contrib.apps.drf_integration.form_elements.fields.null_boolean -- fobi.contrib.apps.drf_integration.form_elements.fields.password -- fobi.contrib.apps.drf_integration.form_elements.fields.radio -- fobi.contrib.apps.drf_integration.form_elements.fields.range_select -- fobi.contrib.apps.drf_integration.form_elements.fields.regex -- fobi.contrib.apps.drf_integration.form_elements.fields.select -- fobi.contrib.apps.drf_integration.form_elements.fields.select_multiple -- fobi.contrib.apps.drf_integration.form_elements.fields.select_multiple_with_max -- fobi.contrib.apps.drf_integration.form_elements.fields.slider -- fobi.contrib.apps.drf_integration.form_elements.fields.slug -- fobi.contrib.apps.drf_integration.form_elements.fields.text -- fobi.contrib.apps.drf_integration.form_elements.fields.textarea -- fobi.contrib.apps.drf_integration.form_elements.fields.time -- fobi.contrib.apps.drf_integration.form_elements.fields.url -- fobi.contrib.apps.drf_integration.form_elements.content.content_image -- fobi.contrib.apps.drf_integration.form_elements.content.content_image_url -- fobi.contrib.apps.drf_integration.form_elements.content.content_text -- fobi.contrib.apps.drf_integration.form_elements.content.content_video -- fobi.contrib.apps.drf_integration.form_handlers.db_store -- fobi.contrib.apps.drf_integration.form_handlers.http_repost -- fobi.contrib.apps.drf_integration.form_handlers.mail - -Installation -~~~~~~~~~~~~ -Versions -######## -Was made with ``djangorestframework`` 3.6.2. May work on earlier versions, -although not guaranteed. - -See the `requirements file -`_. - -your_project/settings.py -######################## -See the `example settings file -`_. - -.. code-block:: python - - INSTALLED_APPS = list(INSTALLED_APPS) - INSTALLED_APPS += [ - # ... - # Here should come a list of form element plugins of the core - # package, followed by the list of form handler plugins of the core - # package, followed by the list of themes of the core package and - # all other apps that do matter. - # ... - 'rest_framework', # Django REST framework - 'fobi.contrib.apps.drf_integration', # DRF integration app - - # DRF integration form element plugins - fields - 'fobi.contrib.apps.drf_integration.form_elements.fields.boolean', - 'fobi.contrib.apps.drf_integration.form_elements.fields.checkbox_select_multiple', - 'fobi.contrib.apps.drf_integration.form_elements.fields.date', - 'fobi.contrib.apps.drf_integration.form_elements.fields.datetime', - 'fobi.contrib.apps.drf_integration.form_elements.fields.decimal', - 'fobi.contrib.apps.drf_integration.form_elements.fields.email', - 'fobi.contrib.apps.drf_integration.form_elements.fields.file', - 'fobi.contrib.apps.drf_integration.form_elements.fields.float', - 'fobi.contrib.apps.drf_integration.form_elements.fields.hidden', - 'fobi.contrib.apps.drf_integration.form_elements.fields.input', - 'fobi.contrib.apps.drf_integration.form_elements.fields.integer', - 'fobi.contrib.apps.drf_integration.form_elements.fields.ip_address', - 'fobi.contrib.apps.drf_integration.form_elements.fields.null_boolean', - 'fobi.contrib.apps.drf_integration.form_elements.fields.password', - 'fobi.contrib.apps.drf_integration.form_elements.fields.radio', - 'fobi.contrib.apps.drf_integration.form_elements.fields.range_select', - 'fobi.contrib.apps.drf_integration.form_elements.fields.regex', - 'fobi.contrib.apps.drf_integration.form_elements.fields.select', - 'fobi.contrib.apps.drf_integration.form_elements.fields.select_multiple', - 'fobi.contrib.apps.drf_integration.form_elements.fields.select_multiple_with_max', - 'fobi.contrib.apps.drf_integration.form_elements.fields.slider', - 'fobi.contrib.apps.drf_integration.form_elements.fields.slug', - 'fobi.contrib.apps.drf_integration.form_elements.fields.text', - 'fobi.contrib.apps.drf_integration.form_elements.fields.textarea', - 'fobi.contrib.apps.drf_integration.form_elements.fields.time', - 'fobi.contrib.apps.drf_integration.form_elements.fields.url', - - # DRF integration form element plugins - presentational - 'fobi.contrib.apps.drf_integration.form_elements.content.content_image', - 'fobi.contrib.apps.drf_integration.form_elements.content.content_image_url', - 'fobi.contrib.apps.drf_integration.form_elements.content.content_text', - 'fobi.contrib.apps.drf_integration.form_elements.content.content_video', - - # DRF integration form handler plugins - 'fobi.contrib.apps.drf_integration.form_handlers.db_store', - 'fobi.contrib.apps.drf_integration.form_handlers.mail', - 'fobi.contrib.apps.drf_integration.form_handlers.http_repost', - # ... - ] - -your_project/urls.py -#################### -Add the following code to the main ``urls.py`` of your project: - -.. code-block:: python - - # Conditionally including django-rest-framework integration app - if 'fobi.contrib.apps.drf_integration' in settings.INSTALLED_APPS: - from fobi.contrib.apps.drf_integration.urls import fobi_router - urlpatterns += [ - url(r'^api/', include(fobi_router.urls)) - ] - -Usage -~~~~~ -If you have followed the steps above precisely, you would be able to access -the API using ``http://localhost:8000/api/fobi-form-entry/``. - -Actions/methods supported: - -LIST -#### -.. code-block:: text - - GET /api/fobi-form-entry/ - -Lists all the forms available. Anonymous users would see the list of all -public forms. Authenticated users would see their own forms in addition -to the public forms. - -OPTIONS -####### -.. code-block:: text - - OPTIONS /api/fobi-form-entry/{FORM_SLUG}/ - -Lists all field options for the selected form. Private forms would be only -visible to authenticated users. - -PUT -### -.. code-block:: text - - PUT /api/fobi-form-entry/{FORM_SLUG}/ - - {DATA} - -Callbacks -~~~~~~~~~ -Callbacks work just the same way the core callbacks work. - -fobi_form_callbacks.py -###################### -.. code-block:: python - - from fobi.base import ( - integration_form_callback_registry, - IntegrationFormCallback, - ) - - from fobi.constants import ( - CALLBACK_BEFORE_FORM_VALIDATION, - CALLBACK_FORM_INVALID, - CALLBACK_FORM_VALID, - CALLBACK_FORM_VALID_AFTER_FORM_HANDLERS, - CALLBACK_FORM_VALID_BEFORE_SUBMIT_PLUGIN_FORM_DATA, - ) - - from fobi.contrib.apps.drf_integration import UID as INTEGRATE_WITH - - - class DRFSaveAsFooItem(IntegrationFormCallback): - """Save the form as a foo item, if certain conditions are met.""" - - stage = CALLBACK_FORM_VALID - integrate_with = INTEGRATE_WITH - - def callback(self, form_entry, request, **kwargs): - """Custom callback login comes here.""" - logger.debug("Great! Your form is valid!") - - - class DRFDummyInvalidCallback(IntegrationFormCallback): - """Saves the form as a foo item, if certain conditions are met.""" - - stage = CALLBACK_FORM_INVALID - integrate_with = INTEGRATE_WITH - - def callback(self, form_entry, request, **kwargs): - """Custom callback login comes here.""" - logger.debug("Damn! You've made a mistake, boy!") - -Testing -~~~~~~~ -To test Django REST framework integration package only, run the following -command: - -.. code-block:: sh - - ./runtests.py src/fobi/tests/test_drf_integration.py - -or use plain Django tests: - -.. code-block:: sh - - ./manage.py test fobi.tests.test_drf_integration --settings=settings.test - -Limitations -~~~~~~~~~~~ -Certain fields are not available yet (relational fields). - - -Form elements -------------- - - -Content form element -~~~~~~~~~~~~~~~~~~~~ -Presentational form elements for ``drf_integration``. - - -fobi.contrib.apps.drf_integration.form_elements.content.content_image -##################################################################### -A ``django-fobi`` ContentImage plugin for integration with -``Django REST framework``. Makes use of the -``fobi.contrib.apps.drf_integration.fields.ContentImage``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.content.content_image`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.content.content_image', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -Usage -^^^^^ -Unlike standard fields, ``ContentImage`` field is purely presentational. -You're not supposed to make write actions on it (it won't work). Neither -will it be displayed in the browsable API (list/retrieve actions). However, -it will be listed in the options action call. - -**Sample JSON response fragment** - -.. code-block:: javascript - - "actions": { - "PUT": { - // ... - "content_image_89c8c319-195b-487a-a44d-f59ef14a5d44": { - "type": "content", - "required": false, - "read_only": true, - "contenttype": "image", - "content": "\n

\n\n\n\n\n\"Lorem\n\n\n

\n", - "raw": { - "file": "/media/fobi_plugins/content_image/test-image.jpg", - "alt": "Lorem ipsum", - "fit_method": "center", - "size": "500x500" - } - }, - // ... - } - } - -**JSON response fragment explained** - -- ``type`` (str): Set to "content" for all presentational form elements. -- ``contenttype`` (str): Set to "image" for ``ContentImage`` field. -- ``content`` (str): Representation of the content. Rendered partial HTML. -- ``raw`` (json dict): Raw attributes of the ``ContentImage`` plugin. Contains - "file", "alt", "fit_method" and "size" attributes. - - -fobi.contrib.apps.drf_integration.form_elements.content.content_image_url -######################################################################### -A ``django-fobi`` ContentImageURL plugin for integration with -``Django REST framework``. Makes use of the -``fobi.contrib.apps.drf_integration.fields.ContentImage``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.content.content_image_url`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.content.content_image_url', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -Usage -^^^^^ -Unlike standard fields, ``ContentImageURL`` field is purely presentational. -You're not supposed to make write actions on it (it won't work). Neither -will it be displayed in the browsable API (list/retrieve actions). However, -it will be listed in the options action call. - -**Sample JSON response fragment** - -.. code-block:: javascript - - "actions": { - "PUT": { - // ... - "content_image_89c8c319-195b-487a-a44d-f59ef14a5d44": { - "type": "content", - "required": false, - "read_only": true, - "contenttype": "image", - "content": "\n

\n\n\n\n\n\"Lorem\n\n\n

\n", - "raw": { - "url": "http://example.com/media/test-image.jpg", - "alt": "Lorem ipsum", - "fit_method": "fit_width", - "size": "500x500" - } - }, - // ... - } - } - -**JSON response fragment explained** - -- ``type`` (str): Set to "content" for all presentational form elements. -- ``contenttype`` (str): Set to "image" for ``ContentImageURL`` field. -- ``content`` (str): Representation of the content. Rendered partial HTML. -- ``raw`` (json dict): Raw attributes of the ``ContentImageURL`` plugin. - Contains "url", "alt", "fit_method" and "size" attributes. - - -fobi.contrib.apps.drf_integration.form_elements.content.content_text -#################################################################### -A ``django-fobi`` ContentText plugin for integration with -``Django REST framework``. Makes use of the -``fobi.contrib.apps.drf_integration.fields.ContentText``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.content.content_text`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.content.content_text', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -Usage -^^^^^ -Unlike standard fields, ``ContentText`` field is purely presentational. -You're not supposed to make write actions on it (it won't work). Neither -will it be displayed in the browsable API (list/retrieve actions). However, -it will be listed in the options action call. - -**Sample JSON response fragment** - -.. code-block:: javascript - - "actions": { - "PUT": { - // ... - "content_text_89c8c319-195b-487a-a44d-f59ef14a5d44": { - "type": "content", - "required": false, - "read_only": true, - "contenttype": "text", - "content": "\n

\n\nLorem ipsum dolor sit amet.\n\n\n

\n", - "raw": { - "text": "Lorem ipsum dolor sit amet." - } - }, - // ... - } - } - -**JSON response fragment explained** - -- ``type`` (str): Set to "content" for all presentational form elements. -- ``contenttype`` (str): Set to "text" for ``ContentText`` field. -- ``content`` (str): Representation of the content. Rendered partial HTML. -- ``raw`` (json dict): Raw attributes of the ``ContentText`` plugin. Contains - "text" attribute. - - -fobi.contrib.apps.drf_integration.form_elements.content.content_video -##################################################################### -A ``django-fobi`` ContentVideo plugin for integration with -``Django REST framework``. Makes use of the -``fobi.contrib.apps.drf_integration.fields.ContentVideo``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.content.content_video`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.content.content_video', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -Usage -^^^^^ -Unlike standard fields, ``ContentVideo`` field is purely presentational. -You're not supposed to make write actions on it (it won't work). Neither -will it be displayed in the browsable API (list/retrieve actions). However, -it will be listed in the options action call. - -**Sample JSON response fragment** - -.. code-block:: javascript - - "actions": { - "PUT": { - // ... - "content_video_41a6b951-e6f9-4f08-ada6-3b109aa9a72f": { - "type": "content", - "required": false, - "read_only": true, - "contenttype": "video", - "content": "\n\n", - "raw": { - "title": "Cras risus ipsum faucibus", - "url": "https://www.youtube.com/watch?v=3P1qcVcs4Ik", - "size": "500x400" - } - }, - // ... - } - } - -**JSON response fragment explained** - -- ``type`` (str): Set to "content" for all presentational form elements. -- ``contenttype`` (str): Set to "video" for ``ContentVideo`` field. -- ``content`` (str): Representation of the content. Rendered partial HTML. -- ``raw`` (json dict): Raw attributes of the ``ContentVideo`` plugin. Contains - "title", "url" and "size" attributes. - - -Fields -~~~~~~ -Form fields for ``drf_integration``. - - -fobi.contrib.apps.drf_integration.form_elements.fields.boolean -############################################################## -A ``django-fobi`` BooleanField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.BooleanField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.boolean`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.boolean', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.checkbox_select_multiple -############################################################################### -A ``django-fobi`` CharField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.MultipleChoiceField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.checkbox_select_multiple`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.checkbox_select_multiple', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.date -########################################################### -A ``django-fobi`` DateField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.DateField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.date`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.date', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.date_drop_down -##################################################################### -A ``django-fobi`` DateField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.DateField``. - -This plugin has been made primarily for compatibility with ``date_drop_down`` -plugin of the core package. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.date_drop_down`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.date_drop_down', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.datetime -############################################################### -A ``django-fobi`` DateField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.DateTimeField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.datetime`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.datetime', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.decimal -############################################################## -A ``django-fobi`` DecimalField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.DecimalField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.decimal`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.decimal', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.email -############################################################ -A ``django-fobi`` EmailField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.EmailField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.email`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.email', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.file -########################################################### -A ``django-fobi`` FileField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.FileField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.file`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.file', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.float -############################################################ -A ``django-fobi`` FloatField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.FloatField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.float`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.float', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.hidden -############################################################# -A ``django-fobi`` HiddenField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.HiddenField``. - -Note, that in terms of the Django REST framework it is a read-only field. -Any values posted along won't be saved. Initial value would. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.hidden`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.hidden', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.input -############################################################ -A ``django-fobi`` CharField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.CharField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.input`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.input', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.integer -############################################################## -A ``django-fobi`` IntegerField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.IntegerField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.integer`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.integer', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.ip_address -################################################################# -A ``django-fobi`` IPAddressField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.IPAddressField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.ip_address`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.ip_address', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.null_boolean -################################################################### -A ``django-fobi`` NullBooleanField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.NullBooleanField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.null_boolean`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.null_boolean', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.password -############################################################### -A ``django-fobi`` CharField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.CharField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.password`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.password', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.radio -############################################################ -A ``django-fobi`` CharField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.ChoiceField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.radio`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.radio', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.range_select -################################################################### -A ``django-fobi`` ChoiceField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.ChoiceField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.range_select`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.range_select', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.regex -############################################################ -A ``django-fobi`` RegexField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.RegexField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.regex`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.regex', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.select -############################################################# -A ``django-fobi`` ChoiceField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.ChoiceField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.select`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.select', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.select_multiple -###################################################################### -A ``django-fobi`` CharField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.MultipleChoiceField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.select_multiple`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.select_multiple', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.select_multiple -###################################################################### -A ``django-fobi`` CharField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.MultipleChoiceField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.select_multiple`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.select_multiple', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.slider -############################################################# -A ``django-fobi`` ChoiceField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.ChoiceField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.slider`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.slider', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.slug -########################################################### -A ``django-fobi`` SlugField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.SlugField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.slug`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.slug', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.text -########################################################### -A ``django-fobi`` CharField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.CharField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.text`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.text', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.textarea -############################################################### -A ``django-fobi`` CharField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.CharField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.textarea`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.textarea', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.time -########################################################### -A ``django-fobi`` TimeField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.TimeField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.time`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.time', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_elements.fields.url -########################################################## -A ``django-fobi`` URLField plugin for integration with -``Django REST framework``. Makes use of the -``rest_framework.fields.URLField``. - -Installation -^^^^^^^^^^^^ -1. Add ``fobi.contrib.apps.drf_integration.form_elements.fields.time`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_elements.fields.url', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -Form handlers -------------- -Form handlers for ``drf_integration``. - - -fobi.contrib.apps.drf_integration.form_handlers.db_store -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A ``django-fobi`` Mail form handler plugin for integration -with ``Django REST framework``. Saves submitted form data into the -``SavedFormDataEntry`` model. - -Installation -############ -1. Add ``fobi.contrib.apps.drf_integration.form_handlers.db_store`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_handlers.db_store', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py migrate - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_handlers.http_repost -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A ``django-fobi`` HTTP repost form handler plugin for integration -with ``Django REST framework``. Submits the form to another endpoint specified. - -Installation -############ -1. Add ``fobi.contrib.apps.drf_integration.form_handlers.http_respost`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_handlers.http_repost', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.drf_integration.form_handlers.mail -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A ``django-fobi`` Mail form handler plugin for integration -with ``Django REST framework``. Submits the form data by email to the -specified email address. - -Installation -############ -1. Add ``fobi.contrib.apps.drf_integration.form_handlers.mail`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - -.. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.apps.drf_integration.form_handlers.mail', - # ... - ) - -2. In the terminal type: - -.. code-block:: sh - - ./manage.py migrate - - ./manage.py fobi_sync_plugins - -3. Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.apps.feincms_integration -------------------------------------- -A ``django-fobi`` integration with FeinCMS. - -Installation -~~~~~~~~~~~~ -Versions -######## -See the `requirements file -`_. - -your_project/settings.py -######################## -See the `example settings file -`_. - -.. code-block:: python - - INSTALLED_APPS = list(INSTALLED_APPS) - INSTALLED_APPS += [ - 'feincms', # FeinCMS - - 'fobi.contrib.apps.feincms_integration', # Fobi FeinCMS app - - 'page', # Example - ] - - FEINCMS_RICHTEXT_INIT_CONTEXT = { - 'TINYMCE_JS_URL': STATIC_URL + 'tiny_mce/tiny_mce.js', - } - -your_project/page/models.py -########################### -.. code-block:: python - - from django.utils.translation import ugettext_lazy as _ - - from feincms.module.page.models import Page - from feincms.content.raw.models import RawContent - from feincms.content.richtext.models import RichTextContent - # Import the ``django-fobi`` widget. - from fobi.contrib.apps.feincms_integration.widgets import FobiFormWidget - - Page.register_extensions('feincms.module.extensions.translations',) - - # Register basic template. - Page.register_templates( - { - 'title': _(u"Base template"), - 'path': 'page/base.html', - 'key': 'page_base', - 'regions': ( - ('main', _(u"Main")), - ('sidebar', _(u"Sidebar")), - ) - }, - ) - - # Standard content types - Page.create_content_type(RawContent) - Page.create_content_type(RichTextContent) - - # Register the ``django-fobi`` widget. - Page.create_content_type(FobiFormWidget) - -your_project/admin.py -##################### -.. code-block:: python - - from django.contrib import admin - - from feincms.module.page.modeladmins import PageAdmin - - from page.models import Page - - admin.site.register(Page, PageAdmin) - -Information for developers -########################## -Template rendering -^^^^^^^^^^^^^^^^^^ -The embed FeinCMS widget is rendered with use of two theme templates: - -- ``view_embed_form_entry_ajax_template``: Used for rendering the form. -- ``embed_form_entry_submitted_ajax_template``: Used for rendering the form - sent event. - -Using custom templates for rendering the widget -############################################### -In the widget, you can specify a template which you want to be used for -rendering the form or the form-sent event. - -Example: - -.. code-block:: python - - FOBI_FEINCMS_INTEGRATION_FORM_TEMPLATE_CHOICES = ( - ("yourapp/custom_view_embed_form_v1.html", - "Custom embed form view template #1"), - ("yourapp/custom_view_embed_form_v2.html", - "Custom embed form view template #2"), - ) - -Same goes for form-sent templates. - -.. code-block:: python - - FOBI_FEINCMS_INTEGRATION_SUCCESS_PAGE_TEMPLATE_CHOICES = ( - ("yourapp/custom_embed_form_submitted_v1.html", - "Custom form-sent template #1"), - ("yourapp/custom_embed_form_submitted_v2.html", - "Custom form-sent template #2"), - ) - -Registering a template in the ``FORM_TEMPLATE_CHOICES`` makes it available -for all the themes. If you rather want to use different custom templates -for different themes, use the ``FOBI_CUSTOM_THEME_DATA`` as shown in the -example below. - -.. code-block:: python - - FOBI_CUSTOM_THEME_DATA = { - 'bootstrap3': { - 'feincms_integration': { - 'form_template_choices': [ - ('fobi/bootstrap3_extras/view_embed_form.html', - "Custom bootstrap3 embed form view template"), - ], - 'success_page_template_choices': [ - ('fobi/bootstrap3_extras/embed_form_submitted.html', - "Custom bootstrap3 embed form entry submitted template"), - ], - }, - }, - 'foundation5': { - 'feincms_integration': { - 'form_template_choices': [ - ('fobi/foundation5_extras/view_embed_form.html', - "Custom foundation5 embed form view template"), - ], - 'success_page_template_choices': [ - ('fobi/foundation5_extras/embed_form_submitted.html', - "Custom foundation5 embed form entry submitted template"), - ], - }, - }, - } - -Usage -~~~~~ -The ``fobi.contrib.apps.feincms_integration.widgets.FobiFormWidget`` consists -of the following fields: - -- Form: The form to be used. -- Form template name: Template to be used to render the embed form. -- Hide form title: If checked, no form title would be shown. -- Form title: Overrides the standard form title. -- Submit button text: Overrides the default submit button text. -- Success page template name: Template to be used to render the embed form-sent - event. -- Hide success page title: If checked, no form-sent title would be shown. -- Success page title: Overrides the form-sent title. -- Success page text: Overrides the form-sent text. - - -fobi.contrib.apps.mezzanine_integration ---------------------------------------- -A ``django-fobi`` integration with Mezzanine. - -Installation -~~~~~~~~~~~~ -Versions -######## -See the `requirements file -`_. - -your_project/settings.py -######################## -See the `example settings file -`_. - -.. code-block:: python - - INSTALLED_APPS = list(INSTALLED_APPS) - INSTALLED_APPS += [ - # Standard mezzanine apps - - 'fobi.contrib.apps.mezzanine_integration', # Fobi Mezzanine app - ] - -Information for developers -~~~~~~~~~~~~~~~~~~~~~~~~~~ -Template rendering -################## -The form embed into Mezzanine page is rendered with use of two theme templates: - -- ``view_embed_form_entry_ajax_template``: Used for rendering the form. -- ``embed_form_entry_submitted_ajax_template``: Used for rendering the form - sent event. - -Using custom templates for rendering the form -############################################# -In the widget, you can specify a template which you want to be used for -rendering the form or the form-sent event. - -Example: - -.. code-block:: python - - FOBI_MEZZANINE_INTEGRATION_FORM_TEMPLATE_CHOICES = ( - ("yourapp/custom_view_embed_form_v1.html", - "Custom embed form view template #1"), - ("yourapp/custom_view_embed_form_v2.html", - "Custom embed form view template #2"), - ) - -Same goes for form-sent templates. - -.. code-block:: python - - FOBI_MEZZANINE_INTEGRATION_SUCCESS_PAGE_TEMPLATE_CHOICES = ( - ("yourapp/custom_embed_form_submitted_v1.html", - "Custom form-sent template #1"), - ("yourapp/custom_embed_form_submitted_v2.html", - "Custom form-sent template #2"), - ) - -Registering a template in the ``FORM_TEMPLATE_CHOICES`` makes it available -for all the themes. If you rather want to use different custom templates -for different themes, use the ``FOBI_CUSTOM_THEME_DATA`` as shown in the -example below. - -.. code-block:: python - - FOBI_CUSTOM_THEME_DATA = { - 'bootstrap3': { - 'mezzanine_integration': { - 'form_template_choices': [ - ('fobi/bootstrap3_extras/view_embed_form.html', - "Custom bootstrap3 embed form view template"), - ], - 'success_page_template_choices': [ - ('fobi/bootstrap3_extras/embed_form_submitted.html', - "Custom bootstrap3 embed form entry submitted template"), - ], - }, - }, - 'foundation5': { - 'mezzanine_integration': { - 'form_template_choices': [ - ('fobi/foundation5_extras/view_embed_form.html', - "Custom foundation5 embed form view template"), - ], - 'success_page_template_choices': [ - ('fobi/foundation5_extras/embed_form_submitted.html', - "Custom foundation5 embed form entry submitted template"), - ], - }, - }, - } - -Usage -~~~~~ -The ``fobi`` page model -####################### -The ``fobi.contrib.apps.mezzanine_integration.models.FobiFormPage`` consists -of the following fields: - -- Form: The form to be used. -- Form template name: Template to be used to render the embed form. -- Hide form title: If checked, no form title would be shown. -- Form title: Overrides the standard form title. -- Submit button text: Overrides the default submit button text. -- Success page template name: Template to be used to render the embed form-sent - event. -- Hide success page title: If checked, no form-sent title would be shown. -- Success page title: Overrides the form-sent title. -- Success page text: Overrides the form-sent text. - -Steps described -############### -1. If you use the mezzanine `example - `_ - project, to start go to the http://localhost:8003/fobi/ URL and create a - form. -2. Then go to http://localhost:8003/admin/pages/page/ and add a new `Fobi form` - page. -3. Choose the form and optionally - override the form settings and then - save the page. -4. See the page in the front-end. - - -fobi.contrib.plugins.form_elements.content.content_image --------------------------------------------------------- -A ``Fobi`` Image form element plugin. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.content.content_image`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'easy_thumbnails', - 'fobi.contrib.plugins.form_elements.content.content_image', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) Additionally, for the fine tuning, see the - ``fobi.contrib.plugins.form_elements.content.content_image.defaults`` - module. If necessary, override the settings by prepending - ``FOBI_PLUGIN_CONTENT_IMAGE_`` to the desired variable name from the - above mentioned ``defaults`` module. - - -fobi.contrib.plugins.form_elements.content.content_image_url ------------------------------------------------------------- -A ``Fobi`` ImageURL form element plugin. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.content.content_image_url`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.content.content_image_url', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) Additionally, for the fine tuning, see the - ``fobi.contrib.plugins.form_elements.content.content_image_url.defaults`` - module. If necessary, override the settings by prepending - ``FOBI_PLUGIN_CONTENT_IMAGE_URL_`` to the desired variable name from the - above mentioned ``defaults`` module. - - -fobi.contrib.plugins.form_elements.content.content_text -------------------------------------------------------- -A ``Fobi`` Text form element plugin. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.content.content_text`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.content.content_text', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) Additionally, for the fine tuning, see the - ``fobi.contrib.plugins.form_elements.content.content_text.defaults`` - module. If necessary, override the settings by prepending - ``FOBI_PLUGIN_CONTENT_TEXT_`` to the desired variable name from the - above mentioned ``defaults`` module. - - By default the content of the text field is stripped using either the - awesome `bleach `_ library or if bleach - is not installed just Django's own `strip_tags` function. To configure - the strip (bleach only) behaviour, two settings are introduced: - - .. code-block:: text - - - ALLOWED_TAGS: - - ALLOWED_ATTRIBUTES: - - The default values are: - - .. code-block:: python - - ALLOWED_TAGS = [ - 'a', - 'abbr', - 'acronym', - 'b', - 'blockquote', - 'code', - 'em', - 'i', - 'li', - 'ol', - 'strong', - 'ul', - ] - - ALLOWED_ATTRIBUTES = { - 'a': ['href', 'title'], - 'abbr': ['title'], - 'acronym': ['title'], - } - - -fobi.contrib.plugins.form_elements.content.content_video --------------------------------------------------------- -A ``Fobi`` Video form element plugin. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.content.content_video`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.content.content_video', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) Additionally, for the fine tuning, see the - ``fobi.contrib.plugins.form_elements.content.content_video.defaults`` - module. If necessary, override the settings by prepending - ``FOBI_PLUGIN_CONTENT_VIDEO_`` to the desired variable name from the - above mentioned ``defaults`` module. - - -fobi.contrib.plugins.form_elements.fields.boolean -------------------------------------------------- -A ``Fobi`` Boolean form field plugin. Makes use of the -``django.forms.fields.BooleanField``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.boolean`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.boolean', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.checkbox_select_multiple ------------------------------------------------------------------- -A ``Fobi`` Select Multiple form field plugin. Makes use of the -``django.forms.fields.MultipleChoiceField`` and -``django.forms.widgets.CheckboxSelectMultiple``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.checkbox_select_multiple`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.checkbox_select_multiple', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) By default, the submitted form value of `select_multiple` - elements is label (human readable representation of the value chosen). - However, that part of the behaviour has been made configurable. You can - choose between the following options: - - Consider the following list of (value, label) choices (the first element in - the tuple is value, the second element is label): - - .. code-block:: python - - [ - ('alpha', 'Alpha'), - ('beta', 'Beta'), - ('gamma', 'Gamma'), - ] - - - "val": `value` (example: "alpha"). - - "repr" (default): `label` (example: "Alpha"). - - "mix": `value (label)` (example: "Alpha (alpha)"). - - Simply set the - ``FOBI_FORM_ELEMENT_CHECKBOX_SELECT_MULTIPLE_SUBMIT_VALUE_AS`` assign one - of the following values: "val", "repr" or "mix" to get the desired - behaviour. - -Usage -~~~~~ -You should be entering a single choice per line. Choice might -consist of just a single value or value/label pair. - -For example: - -.. code-block:: text - - 1 - 2 - alpha, Alpha - beta, Beta - omega - -The following HTML would be made of: - -.. code-block:: html - -
    -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
- - -fobi.contrib.plugins.form_elements.fields.date ----------------------------------------------- -A ``Fobi`` Date form field plugin. Makes use of the -``django.forms.fields.DateField`` and ``django.forms.widgets.DateInput``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.date`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.date', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.date_drop_down --------------------------------------------------------- -A ``Fobi`` Birthday form field plugin. Makes use of the -``django.forms.fields.DateField`` and -``django.forms.extras.widgets.SelectDateWidget``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.date_drop_down`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.date_drop_down', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.datetime --------------------------------------------------- -A ``Fobi`` DateTime form field plugin. Makes use of the -``django.forms.fields.DateTimeField`` and -``django.forms.widgets.DateTimeInput``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.datetime`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.datetime', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.decimal -------------------------------------------------- -A ``Fobi`` Decimal form field plugin. Makes use of the -``django.forms.fields.DecimalField`` and ``django.forms.widgets.NumberInput`` -(falling back to ``django.forms.widgets.TextInput`` for older Django -versions). - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.decimal`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.decimal', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.email ------------------------------------------------ -A ``Fobi`` Email form field plugin. Makes use of the -``django.forms.fields.EmailField`` and ``django.forms.widgets.TextInput``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.email`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.email', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.file ----------------------------------------------- -A ``Fobi`` File form field plugin. Makes use of the -``django.forms.fields.FileField`` and -``django.forms.widgets.ClearableFileInput``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.file`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.file', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) By default uploaded files are stored in the "fobi_plugins/file" directory - of the media root. If you want to change the directory location, - set the ``FOBI_PLUGIN_FIELDS_FILE_FILES_UPLOAD_DIR`` value to the desired - (relative) path. - - -fobi.contrib.plugins.form_elements.fields.float ------------------------------------------------ -A ``Fobi`` Integer form field plugin. Makes use of the -``django.forms.fields.FloatField`` and ``django.forms.widgets.NumberInput`` -(falling back to ``django.forms.widgets.TextInput`` for older Django -versions). - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.float`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.float', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.hidden ------------------------------------------------- -A ``Fobi`` Hidden form field plugin. Makes use of the -``django.forms.fields.CharField`` and ``django.forms.widgets.HiddenInput``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.hidden`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.hidden', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.input ------------------------------------------------ -A generic input form field plugin. Makes use of the -``django.forms.fields.Field`` and ``django.forms.widgets.Input``. -Comes with a lot of options you likely won't use every day. - -The full list of supported HTML properties is listed below: - -- autocomplete -- autofocus -- disabled -- list -- max -- min -- multiple -- pattern -- placeholder -- readonly -- step -- type - -See `w3schools.com `_ for further -explanations. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.input`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.input', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.integer -------------------------------------------------- -A ``Fobi`` Integer form field plugin. Makes use of the -``django.forms.fields.IntegerField`` and ``django.forms.widgets.NumberInput`` -(falling back to ``django.forms.widgets.TextInput`` for older Django -versions). - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.integer`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.integer', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.ip_address ----------------------------------------------------- -A ``Fobi`` Text form field plugin. Makes use of the -``django.forms.fields.GenericIPAddressField`` and -``django.forms.widgets.TextInput``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.ip_address`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.ip_address', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.null_boolean ------------------------------------------------------- -A ``Fobi`` NullBoolean form field plugin. Makes use of the -``django.forms.fields.NullBooleanField`` and -``django.forms.widgets.NullBooleanSelect``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.null_boolean`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.null_boolean', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.password --------------------------------------------------- -A ``Fobi`` Password form field plugin. Makes use of the -``django.forms.fields.CharField`` and ``django.forms.widgets.PasswordInput``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.password`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.password', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.radio ------------------------------------------------ -A ``Fobi`` Radio form field plugin. Makes use of the -``django.forms.fields.ChoiceField`` and ``django.forms.widgets.RadioSelect``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.radio`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.radio', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) By default, the submitted form value of `radio` - elements is label (human readable representation of the value chosen). - However, that part of the behaviour has been made configurable. You can - choose between the following options: - - Consider the following list of (value, label) choices (the first element in - the tuple is value, the second element is label): - - .. code-block:: python - - [ - ('alpha', 'Alpha'), - ('beta', 'Beta'), - ('gamma', 'Gamma'), - ] - - .. code-block:: text - - - "val": `value` (example: "alpha"). - - "repr" (default): `label` (example: "Alpha"). - - "mix": `value (label)` (example: "Alpha (alpha)"). - - Simply set the - ``FOBI_FORM_ELEMENT_RADIO_SUBMIT_VALUE_AS`` assign one of the following - values: "val", "repr" or "mix" to get the desired behaviour. - -Usage ------ -You should be entering a single choice per line. Choice might -consist of just a single value or value/label pair. - -For example: - -.. code-block:: text - - 1 - 2 - alpha, Alpha - beta, Beta - omega - -The following HTML would be made of: - -.. code-block:: html - - - - -fobi.contrib.plugins.form_elements.fields.range_select ------------------------------------------------------- -A ``Fobi`` RangeSelect form field plugin. Makes use of the -``django.forms.fields.ChoiceField`` and ``django.forms.widgets.Select``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.range_select`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.range_select', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) Ranges are specified within the given min/max values. The default values - are: - - .. code-block:: text - - - INITIAL: 50 - - INITIAL_MAX_VALUE: 100 - - INITIAL_MIN_VALUE: 0 - - MIN_VALUE: 0 - - MAX_VALUE: 100 - - STEP: 1 - - However, you can override each of them in the settings of your project by - prefixing correspondent names with `FOBI_FORM_ELEMENT_RANGE_SELECT_`: - - .. code-block:: text - - - FOBI_FORM_ELEMENT_RANGE_SELECT_INITIAL - - FOBI_FORM_ELEMENT_RANGE_SELECT_INITIAL_MAX_VALUE - - FOBI_FORM_ELEMENT_RANGE_SELECT_INITIAL_MIN_VALUE - - FOBI_FORM_ELEMENT_RANGE_SELECT_MIN_VALUE - - FOBI_FORM_ELEMENT_RANGE_SELECT_MAX_VALUE - - FOBI_FORM_ELEMENT_RANGE_SELECT_STEP - - -fobi.contrib.plugins.form_elements.fields.regex ------------------------------------------------ -A ``Fobi`` Text form field plugin. Makes use of the -``django.forms.fields.RegexField`` and ``django.forms.widgets.TextInput``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.regex`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.regex', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.select ------------------------------------------------- -A ``Fobi`` Select form field plugin. Makes use of the -``django.forms.fields.ChoiceField`` and ``django.forms.widgets.Select``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.select`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.select', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) By default, the submitted form value of `select` - elements is label (human readable representation of the value chosen). - However, that part of the behaviour has been made configurable. You can - choose between the following options: - - Consider the following list of (value, label) choices (the first element in - the tuple is value, the second element is label): - - .. code-block:: python - - [ - ('alpha', 'Alpha'), - ('beta', 'Beta'), - ('gamma', 'Gamma'), - ] - - .. code-block:: text - - - "val": `value` (example: "alpha"). - - "repr" (default): `label` (example: "Alpha"). - - "mix": `value (label)` (example: "Alpha (alpha)"). - - Simply set the - ``FOBI_FORM_ELEMENT_SELECT_SUBMIT_VALUE_AS`` assign one of the following - values: "val", "repr" or "mix" to get the desired behaviour. - -Usage -~~~~~ -You should be entering a single choice per line. Choice might -consist of just a single value or value/label pair. - -For example: - -.. code-block:: text - - 1 - 2 - alpha, Alpha - beta, Beta - omega - -The following HTML would be made of: - -.. code-block:: html - - - - -fobi.contrib.plugins.form_elements.fields.select_model_object -------------------------------------------------------------- -A ``Fobi`` Select Model Object form field plugin. Makes use of the -``django.forms.models.ModelChoiceField`` and ``django.forms.widgets.Select``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.select_model_object`` to - the ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.select_model_object', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) Make sure to take a look at - ``fobi.contrib.plugins.form_elements.fields.select_model_object.defaults.IGNORED_MODELS``. - If necessary, override it in your `settings` as shown in the example below: - - .. code-block:: python - - FOBI_FORM_ELEMENT_SELECT_MODEL_OBJECT_IGNORED_MODELS = [ - 'auth.User', - 'auth.Group', - ] - -(5) By default, the submitted form value of `select_model_object` elements is - `app_label.model_name.object_pk.object_repr`. However, that part of the - behaviour has been made configurable. You can choose between the following - options: - - .. code-block:: text - - - "val": `app_label.model_name.object_pk.object_repr`. - - "repr": `object_repr` (uses the ``__unicode__`` method of the model). - - "mix" (default): `app_label.model_name.object_pk.object_repr`. - - Simply set the ``FOBI_FORM_ELEMENT_SELECT_MODEL_OBJECT_SUBMIT_VALUE_AS`` - assign one of the following values: "val", "repr" or "mix" to get the - desired behaviour. - - -fobi.contrib.plugins.form_elements.fields.select_mptt_model_object ------------------------------------------------------------------- -A ``Fobi`` Select MPTT Model Object form field plugin. Makes use of the -``mptt.fields.TreeNodeChoiceField`` and ``django.forms.widgets.Select``. - -Installation -~~~~~~~~~~~~ -Install `django-mptt` -##################### -Taken from django-mptt `Getting started -`_. - -1. Download ``django-mptt`` using pip by running: - -.. code-block:: sh - - pip install django-mptt - -2. Add ``mptt`` to the ``INSTALLED_APPS`` in your ``settings.py``. - -Install `select_mptt_model_object` plugin -######################################### -(1) Add ``mptt`` and - ``fobi.contrib.plugins.form_elements.fields.select_mptt_model_object`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'mptt', - 'fobi.contrib.plugins.form_elements.fields.select_mptt_model_object', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) Make sure to take a look at - ``fobi.contrib.plugins.form_elements.fields.select_mptt_model_object.defaults.IGNORED_MODELS``. - If necessary, override it in your `settings` as shown in the example below: - - .. code-block:: python - - FOBI_FORM_ELEMENT_SELECT_MPTT_MODEL_OBJECT_IGNORED_MODELS = [ - 'auth.User', - 'auth.Group', - ] - -(5) By default, the submitted form value of `select_mptt_model_object` elements - is `app_label.model_name.object_pk.object_repr`. However, that part of the - behaviour has been made configurable. You can choose between the following - options: - - .. code-block:: text - - - "val": `app_label.model_name.object_pk.object_repr`. - - "repr": `object_repr` (uses the ``__unicode__`` method of the model). - - "mix" (default): `app_label.model_name.object_pk.object_repr`. - - Simply set the ``FOBI_FORM_ELEMENT_SELECT_MPTT_MODEL_OBJECT_SUBMIT_VALUE_AS`` - assign one of the following values: "val", "repr" or "mix" to get the - desired behaviour. - - -fobi.contrib.plugins.form_elements.fields.select_multiple ---------------------------------------------------------- -A ``Fobi`` Select Multiple form field plugin. Makes use of the -``django.forms.fields.MultipleChoiceField`` and -``django.forms.widgets.SelectMultiple``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.select_multiple`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.select_multiple', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) By default, the submitted form value of `select_multiple` - elements is label (human readable representation of the value chosen). - However, that part of the behaviour has been made configurable. You can - choose between the following options: - - Consider the following list of (value, label) choices (the first element in - the tuple is value, the second element is label): - - .. code-block:: python - - [ - ('alpha', 'Alpha'), - ('beta', 'Beta'), - ('gamma', 'Gamma'), - ] - - .. code-block:: text - - - "val": `value` (example: "alpha"). - - "repr" (default): `label` (example: "Alpha"). - - "mix": `value (label)` (example: "Alpha (alpha)"). - - Simply set the - ``FOBI_FORM_ELEMENT_SELECT_MULTIPLE_SUBMIT_VALUE_AS`` assign one of the - following values: "val", "repr" or "mix" to get the desired behaviour. - -Usage -~~~~~ -You should be entering a single choice per line. Choice might -consist of just a single value or value/label pair. - -For example: - -.. code-block:: text - - 1 - 2 - alpha, Alpha - beta, Beta - omega - -The following HTML would be made of: - -.. code-block:: html - - - - -fobi.contrib.plugins.form_elements.fields.select_multiple_model_objects ------------------------------------------------------------------------ -A ``Fobi`` Select Multiple Model Objects form field plugin. Makes use of the -``django.forms.models.ModelMultipleChoiceField`` and -``django.forms.widgets.SelectMultiple``. - -Installation -~~~~~~~~~~~~ -(1) Add - ``fobi.contrib.plugins.form_elements.fields.select_multiple_model_objects`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.select_multiple_model_objects', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) Make sure to take a look at - ``fobi.contrib.plugins.form_elements.fields.select_multiple_model_objects.defaults.IGNORED_MODELS``. - If necessary, override it in your `settings` as shown in the example below: - - .. code-block:: python - - FOBI_FORM_ELEMENT_SELECT_MULTIPLE_MODEL_OBJECTS_IGNORED_MODELS = [ - 'auth.User', - 'auth.Group', - ] - -(5) By default, the submitted form value of `select_multiple_model_objects` - elements is `app_label.model_name.object_pk.object_repr`. However, that - part of the behaviour has been made configurable. You can choose between - the following options: - - .. code-block:: text - - - "val": `app_label.model_name.object_pk.object_repr`. - - "repr": `object_repr` (uses the ``__unicode__`` method of the model). - - "mix" (default): `app_label.model_name.object_pk.object_repr`. - - Simply set the - ``FOBI_FORM_ELEMENT_SELECT_MULTIPLE_MODEL_OBJECTS_SUBMIT_VALUE_AS`` assign - one of the following values: "val", "repr" or "mix" to get the desired - behaviour. - - -fobi.contrib.plugins.form_elements.fields.select_multiple_mptt_model_objects ----------------------------------------------------------------------------- -A ``Fobi`` Select Multiple MPTT Model Objects form field plugin. Makes use of -the ``mptt.forms.TreeNodeMultipleChoiceField`` and -``django.forms.widgets.SelectMultiple``. - -Installation -~~~~~~~~~~~~ -Install `django-mptt` -##################### -Taken from django-mptt `Getting started -`_. - -1. Download ``django-mptt`` using pip by running: - -.. code-block:: sh - - pip install django-mptt - -2. Add ``mptt`` to the ``INSTALLED_APPS`` in your ``settings.py``. - -Install `select_multiple_mptt_model_objects` plugin -################################################### -(1) Add - ``fobi.contrib.plugins.form_elements.fields.select_multiple_mptt_model_objects`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'mptt', - 'fobi.contrib.plugins.form_elements.fields.select_multiple_mptt_model_objects', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) Make sure to take a look at - ``fobi.contrib.plugins.form_elements.fields.select_multiple_mptt_model_objects.defaults.IGNORED_MODELS``. - If necessary, override it in your `settings` as shown in the example below: - - .. code-block:: python - - FOBI_FORM_ELEMENT_SELECT_MULTIPLE_MPTT_MODEL_OBJECTS_IGNORED_MODELS = [ - 'auth.User', - 'auth.Group', - ] - -(5) By default, the submitted form value of `select_multiple_mptt_model_objects` - elements is `app_label.model_name.object_pk.object_repr`. However, that part - of the behaviour has been made configurable. You can choose between the - following options: - - .. code-block:: text - - - "val": `app_label.model_name.object_pk.object_repr`. - - "repr": `object_repr` (uses the ``__unicode__`` method of the model). - - "mix" (default): `app_label.model_name.object_pk.object_repr`. - - Simply set the - ``FOBI_FORM_ELEMENT_SELECT_MULTIPLE_MPTT_MODEL_OBJECTS_SUBMIT_VALUE_AS`` - assign one of the following values: "val", "repr" or "mix" to get the - desired behaviour. - - -fobi.contrib.plugins.form_elements.fields.select_multiple_with_max ------------------------------------------------------------------- -A ``Fobi`` Select Multiple form field plugin with max choices. Makes use of -the ``django.forms.widgets.SelectMultiple``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.select_multiple_with_max`` - to the ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.select_multiple_with_max', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) By default, the submitted form value of `select_multiple_with_max` - elements is label (human readable representation of the value chosen). - However, that part of the behaviour has been made configurable. You can - choose between the following options: - - Consider the following list of (value, label) choices (the first element in - the tuple is value, the second element is label): - - .. code-block:: python - - [ - ('alpha', 'Alpha'), - ('beta', 'Beta'), - ('gamma', 'Gamma'), - ] - - .. code-block:: text - - - "val": `value` (example: "alpha"). - - "repr" (default): `label` (example: "Alpha"). - - "mix": `value (label)` (example: "Alpha (alpha)"). - - Simply set the - ``FOBI_FORM_ELEMENT_SELECT_MULTIPLE_WITH_MAX_SUBMIT_VALUE_AS`` assign one of the - following values: "val", "repr" or "mix" to get the desired behaviour. - -Usage ------ -You should be entering a single choice per line. Choice might -consist of just a single value or value/label pair. If you enter an integer in -the 'max_choices' field, the user can choose only or less choices. - -For example: - -.. code-block:: text - - 1 - 2 - alpha, Alpha - beta, Beta - omega - -The following HTML would be made of: - -.. code-block:: html - - - - -fobi.contrib.plugins.form_elements.fields.slider ------------------------------------------------- -A ``Fobi`` Percentage form field plugin. Makes use of the -``django.forms.fields.ChoiceField`` and ``django.forms.widgets.Select``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.slider`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.slider', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) Ranges are specified within the given min/max values. The default values - are: - - .. code-block:: text - - - INITIAL: 50 - - INITIAL_MAX_VALUE: 100 - - INITIAL_MIN_VALUE: 0 - - MIN_VALUE: 0 - - MAX_VALUE: 100 - - STEP: 1 - - However, you can override each of them in the settings of your project by - prefixing correspondent names with `FOBI_FORM_ELEMENT_SLIDER_`: - - .. code-block:: text - - - FOBI_FORM_ELEMENT_SLIDER_INITIAL - - FOBI_FORM_ELEMENT_SLIDER_INITIAL_MAX_VALUE - - FOBI_FORM_ELEMENT_SLIDER_INITIAL_MIN_VALUE - - FOBI_FORM_ELEMENT_SLIDER_MIN_VALUE - - FOBI_FORM_ELEMENT_SLIDER_MAX_VALUE - - FOBI_FORM_ELEMENT_SLIDER_STEP - - -fobi.contrib.plugins.form_elements.fields.text ----------------------------------------------- -A ``Fobi`` Text form field plugin. Makes use of the -``django.forms.fields.CharField`` and ``django.forms.widgets.TextInput``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.text`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.text', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.textarea --------------------------------------------------- -A ``Fobi`` Textarea form field plugin. Makes use of the -``django.forms.fields.CharField`` and ``django.forms.widgets.Textarea``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.textarea`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.textarea', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.time ----------------------------------------------- -A ``Fobi`` DateTime form field plugin. Makes use of the -``django.forms.fields.TimeField`` and -``django.forms.widgets.TextInput``. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.time`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.time', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.fields.url ---------------------------------------------- -A ``Fobi`` URL form field plugin. Makes use of the -``django.forms.fields.URLField`` and ``django.forms.widgets.URLInput`` falling -back to ``django.forms.widgets.TextInput`` for older Django versions. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.fields.url`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.fields.url', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.security.captcha ---------------------------------------------------- -A `CAPTCHA `_ form field plugin. Makes -use of the `django-simple-captcha -`_. - -Prerequisites -~~~~~~~~~~~~~ -You will need ``libfreetype6``, otherwise ``django-captcha`` won't work. - -.. code-block:: sh - - sudo apt-get install libfreetype6-dev - -Installation -~~~~~~~~~~~~ -Install `django-simple-captcha` -############################### -Taken from django-simple-captcha `installation instructions -`_. - -(1) Download ``django-simple-captcha`` using pip by running: - - .. code-block:: sh - - pip install django-simple-captcha - -(2) Add ``captcha`` to the ``INSTALLED_APPS`` in your ``settings.py``. - -(3) Run ``python manage.py syncdb`` (or ``python manage.py migrate`` if you are - managing database migrations via South) to create the required database - tables. - -(4) Add an entry to your ``urls.py``: - - .. code-block:: python - - urlpatterns += [ - url(r'^captcha/', include('captcha.urls')), - ] - -Install `fobi` Captcha plugin -############################# -(1) Add ``fobi.contrib.plugins.form_elements.security.captcha`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.security.captcha', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -Troubleshooting and usage limitations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In combination with other captcha solutions -########################################### -At the moment, you can't use both ``CAPTCHA`` -(fobi.contrib.plugins.form_elements.security.captcha) and ``ReCAPTCHA`` -(fobi.contrib.plugins.form_elements.security.recaptcha) plugins alongside due -to app name collision of the ``django-simple-captcha`` and ``django-recaptcha`` -packages. That limitation is likely to be solved in future in the -``django-recaptcha`` package. Until then, you should choose either one or -another, but not both on the same time. - -Usage -~~~~~ -Note, that unlike most of the other form element plugins, default -value for the ``required`` attribute is True, which makes the Captcha -obligatory. Although you could still set it to False, it does not make -much sense to do so. - - -fobi.contrib.plugins.form_elements.security.honeypot ----------------------------------------------------- -A `Honeypot `_ -form field plugin. Just another anti-spam technique. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.security.honeypot`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.security.honeypot', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_elements.security.recaptcha ------------------------------------------------------ -A `ReCAPTCHA `_ form field plugin. -Makes use of the `django-recaptcha -`_. - -Installation -~~~~~~~~~~~~ -Install `django-recaptcha` -########################## -(1) Download ``django-recaptcha`` using pip by running: - - .. code-block:: sh - - pip install django-recaptcha - -(2) Add ``captcha`` to the ``INSTALLED_APPS`` in your ``settings.py``. - -(3) Run ``python manage.py syncdb`` (or ``python manage.py migrate`` if you are - managing database migrations via South) to create the required database - tables. - -Install `fobi` ReCAPTCHA plugin -############################### -(1) Add ``fobi.contrib.plugins.form_elements.security.recaptcha`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.security.recaptcha', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) Specify the following ReCAPTCHA credentials in your settings. - - .. code-block:: text - - - ``RECAPTCHA_PUBLIC_KEY`` - - ``RECAPTCHA_PRIVATE_KEY`` - -Troubleshooting and usage limitations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In combination with other captcha solutions -########################################### -At the moment, you can't use both ``CAPTCHA`` -(fobi.contrib.plugins.form_elements.security.captcha) and ``ReCAPTCHA`` -(fobi.contrib.plugins.form_elements.security.recaptcha) plugins alongside due -to app name collision of the ``django-simple-captcha`` and ``django-recaptcha`` -packages. That limitation is likely to be solved in future in the -``django-recaptcha`` package. Until then, you should choose either one or -another, but not both on the same time. - -If you happen to see errors like "Input error: k: Format of site key was -invalid", make sure to have defined (and filled in properly) the -``RECAPTCHA_PUBLIC_KEY`` and ``RECAPTCHA_PRIVATE_KEY`` in your settnings.py. -See the `following `_ -thread for more information. - -Usage -~~~~~ -Note, that unlike most of the other form element plugins, default -value for the ``required`` attribute is True, which makes the ReCaptcha -obligatory. Although you could still set it to False, it does not make -much sense to do so. - - -fobi.contrib.plugins.form_elements.test.dummy ---------------------------------------------- -A ``Fobi`` Dummy form element plugin. Created for testing purposes. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_elements.test.dummy`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_elements.test.dummy', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_handlers.db_store -------------------------------------------- -A ``Fobi`` Database Store form-/wizard- handler plugin. Saves submitted form -data into the ``SavedFormDataEntry``/``SavedFormWizardDataEntry`` models. - -Dependencies -~~~~~~~~~~~~ -The `xlwt `_ package is required -(optional) for XLS export. If not present, export format falls back -to CSV. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_handlers.db_store`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_handlers.db_store', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py migrate - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - -(4) Add db_store form handler plugin URLs to the urls.py of your project. - - .. code-block:: python - - urlpatterns = [ - # DB Store plugin URLs - url(r'^fobi/plugins/form-handlers/db-store/', - include('fobi.contrib.plugins.form_handlers.db_store.urls')), - ] - - For form wizards do: - - .. code-block:: python - - urlpatterns = [ - # DB Store plugin URLs - url(r'^fobi/plugins/form-wizard-handlers/db-store/', - include('fobi.contrib.plugins.form_handlers.db_store.urls.' - 'form_wizard_handlers')), - ] - - -fobi.contrib.plugins.form_handlers.http_repost ----------------------------------------------- -A ``Fobi`` HTTP Repost form handler plugin. Submits the form -data as is to the given endpoint. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_handlers.http_repost`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_handlers.http_repost', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -fobi.contrib.plugins.form_handlers.mail ---------------------------------------- -A ``Fobi`` Mail form handler plugin. Submits the form -data by email to the specified email address. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.plugins.form_handlers.mail`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.plugins.form_handlers.mail', - # ... - ) - -(2) In the terminal type: - - .. code-block:: sh - - ./manage.py fobi_sync_plugins - -(3) Assign appropriate permissions to the target users/groups to be using - the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True. - - -mailchimp_importer ------------------- -A ``django-fobi`` integration with MailChimp. - -This plugin makes it possible to import a form from a MailChimp list. A typical -list URL would be `this `_. In the -listing you would see list names and `Stats` at the right corner. If you click -on it you would see the `Settings` link. Follow it and scroll to the bottom for -the unique id for your list. Now, if you have been successfully authenticated -to the MailChimp API using your API_KEY, you could call the `lists.merge_vars` -method for getting the form. API_KEY could be obtained from the MailChimp -in the `Account API `_. - -For additional information on MailChimp import see the following `article -`_. - -Prerequisites -~~~~~~~~~~~~~ -Python wrapper for the Mailchimp: - -.. code-block:: sh - - pip install mailchimp - -If you are using Django 1.8 or greater, you would need `django-formtools` -package as well: - -.. code-block:: sh - - pip install django-formtools - -Installation -~~~~~~~~~~~~ -your_project/settings.py -######################## -.. code-block:: python - - INSTALLED_APPS = list(INSTALLED_APPS) - INSTALLED_APPS += [ - 'fobi.contrib.plugins.form_importers.mailchimp_importer', - ] - -How it works -~~~~~~~~~~~~ -Assuming that you have configured the `mailchimp_importer` plugin properly and -have the Django running locally on port 8000, accessing the following URL would -bring you to the MailChimp form import wizard. - -- http://localhost:8000/en/fobi/forms/importer/mailchimp/ - -On the first step you would be asked to provide your API_KEY, which is used -to authenticate to the MailChimp in order to fetch your list- and form- -information. The key isn't stored/saved/remembered. Next time you want to -import a form from the same account, you would have to provide it again. - -Development status -~~~~~~~~~~~~~~~~~~ -This part of code is alpha, which means it experimental and needs improvements. - -See the `TODOS `_ -for the full list of planned-, pending- in-development- or to-be-implemented -features. - -If you want to improve it or did make it working, please, make a pull request. - - -fobi.contrib.themes.bootstrap3 ------------------------------- -A ``django-fobi`` Bootstrap 3 theme. Based on the ??? template. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.themes.bootstrap3`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.themes.bootstrap3', - # ... - ) - -(2) Specify ``bootstrap3`` as a default theme in your ``settings.py``: - - .. code-block:: python - - FOBI_DEFAULT_THEME = 'bootstrap3' - - -fobi.contrib.themes.djangocms_admin_style_theme ------------------------------------------------ -A ``django-fobi`` theme in a style of ``djangocms-admin-style`` admin. -Relies on ``djangocms-admin-style`` package and some jQuery UI only. - -jQuery UI "Smoothness" theme comes from `here `_. - -Installation -~~~~~~~~~~~~ -Install `djangocms-admin-style` -############################### -See the original `installation instructions -`_. - -(1) Install the ``djangocms-admin-style`` package. - - .. code-block:: sh - - pip install djangocms-admin-style - -(2) Add ``djangocms_admin_style`` to your ``INSTALLED_APPS`` just before - ``django.contrib.admin``. - -Install `fobi.contrib.themes.djangocms_admin_style_theme` theme -############################################################### -(1) Add ``fobi.contrib.themes.djangocms_admin_style_theme`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.themes.djangocms_admin_style_theme', - # ... - ) - -(2) Specify ``djangocms_admin_style_theme`` as a default theme in your - ``settings.py``: - - .. code-block:: python - - FOBI_DEFAULT_THEME = 'djangocms_admin_style_theme' - - -fobi.contrib.themes.foundation5 -------------------------------- -A ``django-fobi`` Foundation 5 theme. Based on the ??? template, but -entire JS and CSS are taken from Foundation 5 version 5.4.0. The -`following `_ icon set -was used. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.themes.foundation5`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.themes.foundation5', - # ... - ) - -(2) Specify ``foundation5`` as a default theme in your ``settings.py``: - - .. code-block:: python - - FOBI_DEFAULT_THEME = 'foundation5' - - -fobi.contrib.themes.simple --------------------------- -A ``django-fobi`` theme in a style of Django admin. Relies on Django-admin -and some jQuery UI only. - -jQuery UI "Django" theme comes from `here -`_. - -Installation -~~~~~~~~~~~~ -(1) Add ``fobi.contrib.themes.simple`` to the - ``INSTALLED_APPS`` in your ``settings.py``. - - .. code-block:: python - - INSTALLED_APPS = ( - # ... - 'fobi.contrib.themes.simple', - # ... - ) - -(2) Specify ``simple`` as a default theme in your ``settings.py``: - - .. code-block:: python - - FOBI_DEFAULT_THEME = 'simple' - - diff --git a/setup.py b/setup.py index 2526b6c2f..c8ca498af 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ from distutils.version import LooseVersion from setuptools import setup, find_packages -version = '0.11.11' +version = '0.11.12' # *************************************************************************** # ************************** Python version ********************************* diff --git a/src/fobi/__init__.py b/src/fobi/__init__.py index 476ccc53e..7f66a6bed 100644 --- a/src/fobi/__init__.py +++ b/src/fobi/__init__.py @@ -1,6 +1,6 @@ __title__ = 'django-fobi' -__version__ = '0.11.11' -__build__ = 0x000086 +__version__ = '0.11.12' +__build__ = 0x000087 __author__ = 'Artur Barseghyan ' __copyright__ = '2014-2017 Artur Barseghyan' __license__ = 'GPL 2.0/LGPL 2.1' diff --git a/src/fobi/contrib/apps/drf_integration/TODOS.rst b/src/fobi/contrib/apps/drf_integration/TODOS.rst index 3a8b26e2f..c5eea7287 100644 --- a/src/fobi/contrib/apps/drf_integration/TODOS.rst +++ b/src/fobi/contrib/apps/drf_integration/TODOS.rst @@ -35,6 +35,11 @@ Must haves - Improve documentation. - Add more meta options for special fields, such as ``slider``. - Move DRF NoneField to the ``django-nonefield`` package (contrib). +- Add PhoneNumberField plugin. Most of the work on + (serializer) has already been done in the + `django-phonenumber-field + `_, so just make + use of it. Should haves ------------ diff --git a/src/fobi/contrib/apps/drf_integration/base.py b/src/fobi/contrib/apps/drf_integration/base.py index 7324fad80..52f074d2e 100644 --- a/src/fobi/contrib/apps/drf_integration/base.py +++ b/src/fobi/contrib/apps/drf_integration/base.py @@ -36,7 +36,7 @@ class DRFIntegrationFormElementPluginProcessor( IntegrationFormElementPluginProcessor ): - """django-rest-framework field instance processor.""" + """Django REST framework field instance processor.""" def __init__(self, *args, **kwargs): super(DRFIntegrationFormElementPluginProcessor, self).__init__( @@ -45,6 +45,7 @@ def __init__(self, *args, **kwargs): ) self.field_class = kwargs.get('field_class') self.field_kwargs = kwargs.get('field_kwargs', {}) + self.field_metadata = kwargs.get('field_metadata', {}) self.form_element_plugin = kwargs.get('form_element_plugin') self.data = self.form_element_plugin.data \ if self.form_element_plugin \ diff --git a/src/fobi/contrib/apps/drf_integration/dynamic.py b/src/fobi/contrib/apps/drf_integration/dynamic.py index 6b99bbedf..63be0002d 100644 --- a/src/fobi/contrib/apps/drf_integration/dynamic.py +++ b/src/fobi/contrib/apps/drf_integration/dynamic.py @@ -64,6 +64,7 @@ def get_declared_fields(form_entry, has_value=None): """Get declared fields.""" declared_fields = [] + declared_fields_metadata = [] if form_element_entries is None: form_element_entries = form_entry.formelemententry_set.all() @@ -88,17 +89,30 @@ def get_declared_fields(form_entry, ) for plugin_custom_field_instance \ in plugin_custom_field_instances: - # print(plugin_custom_field_instance.field_kwargs) + + # The serializer field class + custom_field_class = plugin_custom_field_instance.field_class( + **plugin_custom_field_instance.field_kwargs + ) + + # Since serializer fields do not accept **kwargs, we need + # to assign `declared_fields_metadata` in the same way as we + # do with `declared_fields`. + declared_fields_metadata.append( + ( + plugin_custom_field_instance.data.name, + plugin_custom_field_instance.field_metadata + ) + ) + declared_fields.append( ( plugin_custom_field_instance.data.name, - plugin_custom_field_instance.field_class( - **plugin_custom_field_instance.field_kwargs - ), + custom_field_class, ) ) - return OrderedDict(declared_fields) + return OrderedDict(declared_fields), OrderedDict(declared_fields_metadata) def assemble_serializer_class(form_entry, @@ -108,7 +122,8 @@ def assemble_serializer_class(form_entry, origin_return_func=None, form_element_entries=None, has_value=None, - declared_fields=None): + declared_fields=None, + declared_fields_metadata=None): """Assemble a serializer class by given entry. :param form_entry: @@ -164,7 +179,7 @@ def assemble_serializer_class(form_entry, # return DynamicSerializer if declared_fields is None: - declared_fields = get_declared_fields( + declared_fields, declared_fields_metadata = get_declared_fields( form_entry, origin=origin, origin_kwargs_update_func=origin_kwargs_update_func, @@ -199,9 +214,22 @@ def _get_declared_fields(cls, bases, attrs): return OrderedDict(fields) + @classmethod + def _get_declared_fields_metadata(cls, bases, attrs): + """Similar to _get_declared_fields, but for metadata.""" + fields = [ + (field_name, obj) for field_name, obj + in declared_fields_metadata.items() + if field_name not in attrs + ] + + return OrderedDict(fields) + def __new__(cls, name, bases, attrs): """Modified version of the original __new__.""" attrs['_declared_fields'] = cls._get_declared_fields(bases, attrs) + attrs['_declared_fields_metadata'] = \ + cls._get_declared_fields_metadata(bases, attrs) return super(SerializerMetaclass, cls).__new__(cls, name, bases, @@ -277,6 +305,19 @@ def get_fields(self): # serializer class. return copy.deepcopy(self._declared_fields) + def get_fields_metadata(self, field_name=None): + """ + Returns a dictionary of {field_name: field_instance}. + """ + # Every new serializer is created with a clone of the field + # instances. This allows users to dynamically modify the fields + # on a serializer instance without affecting every other + # serializer class. + fields_metadata = copy.deepcopy(self._declared_fields_metadata) + if field_name is not None: + return fields_metadata.get(field_name) + return fields_metadata + def get_validators(self): """ Returns a list of validator callables. diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/content/content_image/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/content/content_image/base.py index 50e4c89df..0b7fce2ef 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/content/content_image/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/content/content_image/base.py @@ -41,6 +41,7 @@ def get_custom_field_instances(self, """Get form field instances.""" rendered_image = form_element_plugin.get_rendered_image() + raw_data = form_element_plugin.get_raw_data() field_kwargs = { 'initial': rendered_image, @@ -48,12 +49,19 @@ def get_custom_field_instances(self, 'required': False, 'label': '', 'read_only': True, - 'raw_data': form_element_plugin.get_raw_data(), + 'raw_data': raw_data, + } + field_metadata = { + 'type': 'content', + 'contenttype': 'image', + 'content': rendered_image, + 'raw_data': raw_data } return [ DRFIntegrationFormElementPluginProcessor( field_class=ContentImageField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/content/content_image_url/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/content/content_image_url/base.py index 061205ecb..f0a1f6020 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/content/content_image_url/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/content/content_image_url/base.py @@ -41,6 +41,7 @@ def get_custom_field_instances(self, """Get form field instances.""" rendered_image = form_element_plugin.get_rendered_image() + raw_data = form_element_plugin.get_raw_data() field_kwargs = { 'initial': rendered_image, @@ -48,12 +49,19 @@ def get_custom_field_instances(self, 'required': False, 'label': '', 'read_only': True, - 'raw_data': form_element_plugin.get_raw_data(), + 'raw_data': raw_data, + } + field_metadata = { + 'type': 'content', + 'contenttype': 'image', + 'content': rendered_image, + 'raw_data': raw_data } return [ DRFIntegrationFormElementPluginProcessor( field_class=ContentImageField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/content/content_text/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/content/content_text/base.py index a419dca32..b84389cc6 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/content/content_text/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/content/content_text/base.py @@ -41,19 +41,26 @@ def get_custom_field_instances(self, """Get form field instances.""" rendered_text = form_element_plugin.get_rendered_text() - + raw_data = form_element_plugin.get_raw_data() field_kwargs = { 'initial': rendered_text, 'default': rendered_text, 'required': False, 'label': '', 'read_only': True, - 'raw_data': form_element_plugin.get_raw_data(), + 'raw_data': raw_data, + } + field_metadata = { + 'type': 'content', + 'contenttype': 'text', + 'content': rendered_text, + 'raw_data': raw_data } return [ DRFIntegrationFormElementPluginProcessor( field_class=ContentTextField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/content/content_video/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/content/content_video/base.py index 612cb1249..22f2b6738 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/content/content_video/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/content/content_video/base.py @@ -40,6 +40,7 @@ def get_custom_field_instances(self, **kwargs): """Get form field instances.""" rendered_video = form_element_plugin.get_rendered_video() + raw_data = form_element_plugin.get_raw_data() field_kwargs = { 'initial': rendered_video, @@ -47,12 +48,19 @@ def get_custom_field_instances(self, 'required': False, 'label': '', 'read_only': True, - 'raw_data': form_element_plugin.get_raw_data(), + 'raw_data': raw_data, + } + field_metadata = { + 'type': 'content', + 'contenttype': 'video', + 'content': rendered_video, + 'raw_data': raw_data } return [ DRFIntegrationFormElementPluginProcessor( field_class=ContentVideoField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/fields/decimal/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/fields/decimal/base.py index 3d41e5c67..b92dfb269 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/fields/decimal/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/fields/decimal/base.py @@ -41,6 +41,9 @@ def get_custom_field_instances(self, 'label': form_element_plugin.data.label, 'help_text': form_element_plugin.data.help_text, } + field_metadata = { + 'placeholder': form_element_plugin.data.placeholder + } if form_element_plugin.data.initial: data_initial = decimal.Decimal( @@ -63,18 +66,23 @@ def get_custom_field_instances(self, if form_element_plugin.data.max_digits: data_max_digits = int(form_element_plugin.data.max_digits) field_kwargs.update({'max_digits': data_max_digits}) + field_metadata.update({'max_digits': data_max_digits}) else: field_kwargs.update({'max_digits': 10}) + field_metadata.update({'max_digits': 10}) if form_element_plugin.data.decimal_places: data_decimal_places = int(form_element_plugin.data.decimal_places) field_kwargs.update({'decimal_places': data_decimal_places}) + field_metadata.update({'decimal_places': data_decimal_places}) else: field_kwargs.update({'decimal_places': 5}) + field_metadata.update({'decimal_places': 5}) return [ DRFIntegrationFormElementPluginProcessor( field_class=DecimalField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/fields/email/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/fields/email/base.py index 4078ce086..1874cecff 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/fields/email/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/fields/email/base.py @@ -44,9 +44,15 @@ def get_custom_field_instances(self, field_kwargs.update( {'max_length': int(form_element_plugin.data.max_length)} ) + + field_metadata = { + 'placeholder': form_element_plugin.data.placeholder + } + return [ DRFIntegrationFormElementPluginProcessor( field_class=EmailField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/fields/float/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/fields/float/base.py index 57517b6d6..1244f7d25 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/fields/float/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/fields/float/base.py @@ -39,6 +39,10 @@ def get_custom_field_instances(self, 'label': form_element_plugin.data.label, 'help_text': form_element_plugin.data.help_text, } + field_metadata = { + 'placeholder': form_element_plugin.data.placeholder + } + if form_element_plugin.data.initial: field_kwargs['initial'] = float(form_element_plugin.data.initial) @@ -53,6 +57,7 @@ def get_custom_field_instances(self, return [ DRFIntegrationFormElementPluginProcessor( field_class=FloatField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/fields/input/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/fields/input/base.py index 66aa3fa5d..4259ce3c0 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/fields/input/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/fields/input/base.py @@ -40,13 +40,59 @@ def get_custom_field_instances(self, 'label': form_element_plugin.data.label, 'help_text': form_element_plugin.data.help_text, } + field_metadata = { + 'placeholder': form_element_plugin.data.placeholder + } + + if form_element_plugin.data.autocomplete_value: + field_metadata.update({'autocomplete': 'on'}) + + if form_element_plugin.data.autofocus_value: + field_metadata.update({'autofocus': 'autofocus'}) + + if form_element_plugin.data.disabled_value: + field_metadata.update({'disabled': 'disabled'}) + + if form_element_plugin.data.list_value: + field_metadata.update({'list': form_element_plugin.data.list_value}) + + if form_element_plugin.data.max_value: + field_metadata.update({'max': form_element_plugin.data.max_value}) + + if form_element_plugin.data.min_value: + field_metadata.update({'min': form_element_plugin.data.min_value}) + + if form_element_plugin.data.multiple_value: + field_metadata.update({'multiple': 'multiple'}) + + if form_element_plugin.data.pattern_value: + field_metadata.update( + {'pattern': form_element_plugin.data.pattern_value} + ) + + if form_element_plugin.data.readonly_value: + field_kwargs.update({'read_only': True}) + + if form_element_plugin.data.step_value: + field_metadata.update( + {'step': form_element_plugin.data.step_value} + ) + + if form_element_plugin.data.type_value \ + and form_element_plugin.data.type_value in ('submit', + 'button', + 'reset',): + field_metadata.update({'value': form_element_plugin.data.label}) + if form_element_plugin.data.max_length: field_kwargs.update( {'max_length': int(form_element_plugin.data.max_length)} ) + return [ DRFIntegrationFormElementPluginProcessor( field_class=CharField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/fields/integer/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/fields/integer/base.py index c1ace4e78..f38f89c16 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/fields/integer/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/fields/integer/base.py @@ -39,14 +39,26 @@ def get_custom_field_instances(self, 'label': form_element_plugin.data.label, 'help_text': form_element_plugin.data.help_text, } + + field_metadata = { + 'placeholder': form_element_plugin.data.placeholder + } if form_element_plugin.data.initial: field_kwargs.update( {'initial': int(form_element_plugin.data.initial)} ) + if form_element_plugin.data.max_value: + data_max_value = int(form_element_plugin.data.max_value) + field_kwargs['max_value'] = data_max_value + + if form_element_plugin.data.min_value: + data_min_value = int(form_element_plugin.data.min_value) + field_kwargs['min_value'] = data_min_value return [ DRFIntegrationFormElementPluginProcessor( field_class=IntegerField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/fields/ip_address/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/fields/ip_address/base.py index 86a7c3554..d01ccef9c 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/fields/ip_address/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/fields/ip_address/base.py @@ -40,6 +40,9 @@ def get_custom_field_instances(self, 'label': form_element_plugin.data.label, 'help_text': form_element_plugin.data.help_text, } + field_metadata = { + 'placeholder': form_element_plugin.data.placeholder + } if form_element_plugin.data.max_length: field_kwargs.update( {'max_length': int(form_element_plugin.data.max_length)} @@ -47,6 +50,7 @@ def get_custom_field_instances(self, return [ DRFIntegrationFormElementPluginProcessor( field_class=IPAddressField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/fields/password/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/fields/password/base.py index 9e9c57dca..9e29d61e2 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/fields/password/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/fields/password/base.py @@ -40,6 +40,9 @@ def get_custom_field_instances(self, 'label': form_element_plugin.data.label, 'help_text': form_element_plugin.data.help_text, } + field_metadata = { + 'placeholder': form_element_plugin.data.placeholder + } if form_element_plugin.data.max_length: field_kwargs.update( {'max_length': int(form_element_plugin.data.max_length)} @@ -48,6 +51,7 @@ def get_custom_field_instances(self, return [ DRFIntegrationFormElementPluginProcessor( field_class=CharField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/fields/regex/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/fields/regex/base.py index fd3adb138..0ba6cc8b5 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/fields/regex/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/fields/regex/base.py @@ -41,12 +41,17 @@ def get_custom_field_instances(self, 'help_text': form_element_plugin.data.help_text, 'regex': form_element_plugin.data.regex, } + field_metadata = { + 'placeholder': form_element_plugin.data.placeholder, + 'regex': form_element_plugin.data.regex, + } if form_element_plugin.data.max_length: field_kwargs['max_length'] = form_element_plugin.data.max_length return [ DRFIntegrationFormElementPluginProcessor( field_class=RegexField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/fields/slug/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/fields/slug/base.py index 51ab2fe0b..d6141c2c1 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/fields/slug/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/fields/slug/base.py @@ -40,6 +40,9 @@ def get_custom_field_instances(self, 'label': form_element_plugin.data.label, 'help_text': form_element_plugin.data.help_text, } + field_metadata = { + 'placeholder': form_element_plugin.data.placeholder + } if form_element_plugin.data.max_length: field_kwargs.update( {'max_length': int(form_element_plugin.data.max_length)} @@ -47,6 +50,7 @@ def get_custom_field_instances(self, return [ DRFIntegrationFormElementPluginProcessor( field_class=SlugField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/fields/text/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/fields/text/base.py index 7141374ed..20c1cd8aa 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/fields/text/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/fields/text/base.py @@ -40,13 +40,18 @@ def get_custom_field_instances(self, 'label': form_element_plugin.data.label, 'help_text': form_element_plugin.data.help_text, } + field_metadata = { + 'placeholder': form_element_plugin.data.placeholder + } if form_element_plugin.data.max_length: field_kwargs.update({ 'max_length': int(form_element_plugin.data.max_length) }) + return [ DRFIntegrationFormElementPluginProcessor( field_class=CharField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/fields/textarea/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/fields/textarea/base.py index 6c2f87184..499596045 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/fields/textarea/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/fields/textarea/base.py @@ -40,9 +40,13 @@ def get_custom_field_instances(self, 'label': form_element_plugin.data.label, 'help_text': form_element_plugin.data.help_text, } + field_metadata = { + 'placeholder': form_element_plugin.data.placeholder + } return [ DRFIntegrationFormElementPluginProcessor( field_class=CharField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/form_elements/fields/url/base.py b/src/fobi/contrib/apps/drf_integration/form_elements/fields/url/base.py index cdb256e12..482de22ee 100644 --- a/src/fobi/contrib/apps/drf_integration/form_elements/fields/url/base.py +++ b/src/fobi/contrib/apps/drf_integration/form_elements/fields/url/base.py @@ -40,6 +40,9 @@ def get_custom_field_instances(self, 'label': form_element_plugin.data.label, 'help_text': form_element_plugin.data.help_text, } + field_metadata = { + 'placeholder': form_element_plugin.data.placeholder + } if form_element_plugin.data.max_length: field_kwargs.update( {'max_length': int(form_element_plugin.data.max_length)} @@ -47,6 +50,7 @@ def get_custom_field_instances(self, return [ DRFIntegrationFormElementPluginProcessor( field_class=URLField, - field_kwargs=field_kwargs + field_kwargs=field_kwargs, + field_metadata=field_metadata ) ] diff --git a/src/fobi/contrib/apps/drf_integration/metadata.py b/src/fobi/contrib/apps/drf_integration/metadata.py index c1460b1e4..ce9458d23 100644 --- a/src/fobi/contrib/apps/drf_integration/metadata.py +++ b/src/fobi/contrib/apps/drf_integration/metadata.py @@ -41,23 +41,18 @@ def get_field_info(self, field): of metadata about it. """ field_info = super(FobiMetaData, self).get_field_info(field) - if isinstance( - field, - (ContentTextField, ContentImageField, ContentVideoField) - ): - field_info['type'] = 'content' - - if isinstance(field, ContentTextField): - field_info['contenttype'] = 'text' - field_info['content'] = field.initial - field_info['raw'] = field.raw_data - elif isinstance(field, ContentImageField): - field_info['contenttype'] = 'image' - field_info['content'] = field.initial - field_info['raw'] = field.raw_data - else: - field_info['contenttype'] = 'video' - field_info['content'] = field.initial - field_info['raw'] = field.raw_data + + for __key in ['initial', 'max_value', 'min_value']: + __val = getattr(field, __key, None) + if __val not in (None, ''): + field_info[__key] = __val + + field_metadata = field.root.get_fields_metadata().get( + field.field_name, {} + ) + if field_metadata: + for __k, __val in field_metadata.items(): + if __val not in (None, ''): + field_info[__k] = __val return field_info diff --git a/src/fobi/contrib/apps/drf_integration/serializers.py b/src/fobi/contrib/apps/drf_integration/serializers.py index 0eecbe543..6f0a79618 100644 --- a/src/fobi/contrib/apps/drf_integration/serializers.py +++ b/src/fobi/contrib/apps/drf_integration/serializers.py @@ -1,4 +1,6 @@ # from __future__ import unicode_literals +from collections import OrderedDict + from rest_framework import serializers from rest_framework.reverse import reverse @@ -42,3 +44,9 @@ def get_url(self, obj): args=[obj.slug], request=self.context['request'] ) + + def get_fields_metadata(self, field_name=None): + """Just to make sure nothing breaks.""" + if field_name is not None: + return {} + return OrderedDict([]) diff --git a/src/fobi/contrib/apps/drf_integration/views.py b/src/fobi/contrib/apps/drf_integration/views.py index fb2335a10..51eb0eb5f 100644 --- a/src/fobi/contrib/apps/drf_integration/views.py +++ b/src/fobi/contrib/apps/drf_integration/views.py @@ -76,7 +76,10 @@ def get_object(self): # OK, calling this twice sucks, but fine for the time being. # In future we should try to get rid of additional queries # made double. - declared_fields = get_declared_fields(obj, has_value=self.has_value()) + declared_fields, declared_fields_metadata = get_declared_fields( + obj, + has_value=self.has_value() + ) # Setting all the fields, one by one like they were attributes of # the object (while they are obviously NOT). It's all done just to diff --git a/src/fobi/tests/data.py b/src/fobi/tests/data.py index e2160f696..646883d6e 100644 --- a/src/fobi/tests/data.py +++ b/src/fobi/tests/data.py @@ -475,7 +475,8 @@ '"name": "username", ' '"required": true, ' '"max_length": 200, ' - '"label": "Username"' + '"label": "Username", ' + '"placeholder": "delusionalinsanity"' '}' ) ), @@ -597,7 +598,7 @@ TEST_DYNAMIC_FORMS_PUT_DATA_ALL = { 'username': FAKER.user_name(), 'email': FAKER.email(), - 'age': FAKER.pyint(), + 'age': FAKER.random_int(min=0, max=200), 'drivers_license': FAKER.pybool(), 'special_fields': FAKER.pystr(), 'number_of_children': FAKER.pyint(), @@ -612,7 +613,8 @@ (u'required', True), (u'read_only', False), (u'label', u'Username'), - (u'max_length', 200)])), + (u'max_length', 200), + (u'placeholder', 'delusionalinsanity')])), (u'email', OrderedDict([(u'type', u'email'), (u'required', True), (u'read_only', False), @@ -621,7 +623,8 @@ (u'age', OrderedDict([(u'type', u'integer'), (u'required', True), (u'read_only', False), - (u'label', u'Age')])), + (u'label', u'Age'), + ('max_value', 200)])), (u'drivers_license', OrderedDict([(u'type', u'boolean'), (u'required', False), (u'read_only', False),